home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Experimental BBS Explossion 3
/
Experimental BBS Explossion III.iso
/
games
/
agtm1.zip
/
AGT-DOCS.ZIP
/
MAST-DOC.PT2
< prev
next >
Wrap
Text File
|
1993-06-13
|
154KB
|
4,005 lines
A TYPICAL GAME TURN
┌──────────────────────────────────┐
┌─────────>│ Get Player's Input Command │<─────────┐
│ └─────────────────┬────────────────┘ │
│ │ │
│ V │
│ ┌──────────────────────────────────┐ │
│ │ Parse into Addressee's Name (if │ │
│ │ any), then Noun, Verb, Prep, Obj │ │
│ └─────────────────┬────────────────┘ │
│ │ │
│ V │
│ ┌──────────┐ ┌───────┴──────┐
│ │ Any │ YES │ Give │
│ │ Errors ├────────────>│ Error │
│ │ ? │ │ Message │
│ └────┬─────┘ └──────────────┘
│ │ NO
│ V
│ ┌──────────┐
│ │ ANY │
│ │ Meta- │ NO
│ │ Language ├───────────────┐
│ │ Commands │ │
│ │ ? │ │
│ └────┬─────┘ │
│ │ YES │
│ V │
│ ┌──────────────────────────────────┐ │
│ │ Do meta-commands for ANY Words │ │
│ └─────────────────┬────────────────┘ │
│ │ │
│ V │
│ ┌──────────┐ │
│ YES │ All │ │
│<──────────────────────┤ Done │ │
│ │ ? │ │
│ └────┬─────┘ │
│ │ │
63
│ │ │
│ │ NO │
│ V │
│ ┌──────────────────────────────────┐ │
│ │ Do meta-commands for Input Words │ │
│ └─────────────────┬────────────────┘ │
│ │ │
│ V │
│ ┌──────────┐ │
│ YES │ All │ │
│<──────────────────────┤ Done │ │
│ │ ? │ │
│ └────┬─────┘ │
│ │ NO │
│ V │
│ ┌──────────────────────────────────┐ │
│ │ Do Standard AGT routine for Verb │<───┘
│ └─────────────────┬────────────────┘
│ │
│ V
│ ┌──────────┐
│ │ AFTER │
│ │ Meta- │ NO
│ │ Language ├───────────────┐
│ │ Commands │ │
│ │ ? │ │
│ └────┬─────┘ │
│ │ YES │
│ V │
│ ┌──────────────────────────────────┐ │
│ │ Do meta-commands for AFTER Words │ │
│ └─────────────────┬────────────────┘ │
│ │ │
│ V │
└────────────────────────────┘<────────────────────┘
The meta-command boxes shown above are for Professional Level AGT games
only.
"ANY" META-COMMANDS
Now for a brief description of what these meta-command boxes do in an AGT
game. The first meta box represents the process of testing for conditions
and performing various actions that do not depend on the player having
given a specific Addressee-Verb-Noun-Object combination, i.e., conditions
and actions for ANY words. These kinds of situations are typically
"random" events, such as, (1) having a dwarf appear in the room and throw
an axe at the player, or (2) having a bear (that the player has befriended)
follow him into a new room, or (3) having a voice boom out an announcement
that "The Cave will close in 25 turns", or (4) having the player die
because of some random event (e.g., falling into a pit). During each turn,
these ANY-words meta-commands are checked to see if the commands'
conditions are true and (if true) the meta-commands' designated actions are
taken. This ANY-words process occurs before any specific
vocabulary-dependent meta-commands are executed. Often, the results of
these ANY-words events will make subsequent actions unnecessary and/or
inappropriate. For example, if a player dies a horrible death by a random
dwarf attack, finishing the player's specific command like GET GOLD or
EXAMINE BOOK is certainly inappropriate.
Here are a few examples of typical ANY Meta-Commands:
COMMAND ANY
Present [Blazing torch]
CounterGT 2 75 ; Torch has been lit for at least 75 turns
PrintMessage [Your torch is flickering and growing weaker]
CounterEquals 2 100 ; Torch has been lit for 100 turns
PrintMessage [The torch finally goes out!]
TurnCounterOFF [Torch counter]
SwapLocations [Blazing torch] [unlit torch]
END_COMMAND
COMMAND ANY
NOT Present [Angry guard] ; is not in room (yet)
Chance 10 ; 10 % chance of guard appearing
PutInCurrentRoom [Angry guard] ; put guard in room
PrintMessage [An angry guard suddenly storms into the room!]
END_COMMAND
COMMAND ANY
FlagON [Flag if player has befriended parrot]
PutInCurrentRoom [Parrot] ; Once befriended, parrot stays
VerbIsDirection ; Player is going to new room
PrintMessage [The parrot flies after you and lands nearby.]
END_COMMAND
COMMAND ANY
InRoom [Parrot] ; The parrot is here
FlagOFF [Parrot is not thirsty]
Chance 5 ; 5 % chance of parrot talking
PrintMessage [The parrot squawks "Polly wants a beer!"]
END_COMMAND
COMMAND ANY
InRoom [vampire bat]
Chance 5 ; 5 % chance of being bitten
PrintMessage [The vampire bat bites you on the neck!!]
KillPlayer ; Too bad, but vampire bat bites are fatal!
DoneWithTurn ; No further process for this turn
END_COMMAND
65
META-COMMANDS FOR SPECIFIC WORDS
If the ANY-words meta-commands have not drastically changed the player's
status in the game, then specific Addressee-Verb-Noun-Object combination
meta-commands are tested and (if the conditions are true) the designated
actions are taken. Using these meta-commands is the way that the game
designer can use unique verbs (that are not predefined in AGT). For
example, the game designer could specify a meta-command for KISS PRINCESS
that would first check that the princess was in the room, and (if she was)
print a message like "The princess rudely pushes you away, straightens her
crown and loudly says, 'Stop the hanky-panky, buzzard breath!'" The word
ANY may be substituted for the Verb, or the Noun, or the Object in a
meta-command. For example, a meta-command for ATTACK ANY might be used to
specify a "default" response for the verb ATTACK, such as, printing a
message like "Don't be ridiculous, $verb$ing the $noun$ is really sick!"
If the player entered the command ATTACK THE DOOR, the response would be
"Don't be ridiculous, attacking the door is really sick!"
Meta-commands can also be used to supplement or replace standard verb
processing. For example, a meta-command could be used for verbs like READ,
GET, EAST, etc. This type of substitution of meta-commands for standard
verbs could be used to (1) cause a key to fall out of a book the first time
the player gave the command to GET BOOK, (2) cause a player to go into a
hallucinatory state (i.e., a new room) whenever he gives the command DRINK
THE STRANGE LIQUID, or (3) cause a player to fall to his death on the rocks
far below if he gives the command NORTH (where there is a cliff to the
north in the current room).
If after doing both the ANY-words and the specific vocabulary meta-command
processing for a specific game turn, the player is still alive and further
AGT command processing is still appropriate, then the usual routine for the
player's verb is executed (if the input VERB is a standard AGT verb). This
will be the way that the most of the player's inputs will be handled!
Remember, most player commands in a typical adventure game deal with
manipulating items (GET, DROP, EXAMINE, READ, etc.) and traveling from room
to room (NORTH, SOUTH, UP, EXIT, etc). Standard Level AGT handles these
types of commands quite nicely, and there will seldom be a need for
meta-commands for this type of typical player input.
"AFTER" META-COMMANDS
Finally, AFTER all of the standard processing for the VERB, the Master's
Edition of AGT will do the meta-command processing for AFTER meta-commands.
This is very similar to ANY meta-commands -- except it is done AFTER normal
VERB processing -- rather than before like the ANY commands.
Here are a couple of examples:
66
COMMAND AFTER
FirstVisitToRoom
AtLocation [Living Room]
PrintMessage
You suddenly get a strong desire to look under the cushions on the
couch. However, other than a moldy quarter and two pennies, you don't
find anything of interest.
END_Message
GetIt [Quarter]
GetIt [Pennies]
BlankLine
END_COMMAND
COMMAND AFTER
NOT FirstVisitToRoom
Present [Orc]
Chance 5
PrintMessage "The orc lunges at you and you are history."
KillPlayer
DoneWithTurn
END_COMMAND
INTRODUCTION TO META-COMMANDS
Meta-commands are specified in the .AGT. In the Master's Edition, you may
have up to 900 meta-commands in your game. This capacity will enable the
game designer to develop some very sophisticated adventure games --
especially since the a majority of a player's input will not require any
meta-commands at all.
THE FORMAT OF META-COMMANDS
A typical meta-command in the .AGT file might look like this:
COMMAND BREAK LOCK
InRoom [locked oak door]
NOT InRoom [Evil Wizard]
IsCarrying [Battle Axe]
OR
Present [Sword]
VariableGT [Strength] 90 ; Player has enough strength to swing sword
FlagON [Sword has been pulled free from stone]
OR
IsCarrying [Iron Mace]
VariableGT [Strength] 50 ; Player has enough strength to swing mace
SwapLocations [locked oak door] [open doorway]
PrintMessage [Your blows break the lock and door swings open]
ChangePassageway [north] [throne room]
; open passage to the North into the [throne room]
DoneWithTurn ; No further process for this turn
END_COMMAND
67
Each meta-command begins on a separate line with the keyword COMMAND.
Following this is the input phrase for which this meta-command applies.
The input phrase will be parsed, so you can use extra words for clarity.
After being parsed, AGT will only remember the ADDRESSEE (if there is one),
the VERB, the NOUN and the OBJECT of the COMMAND. If one of these is
missing, there is an implied ANY for the missing item. For example, the
"BREAK LOCK" above is missing an OBJECT (and a preposition), so an implied
OBJECT of ANY is recorded for this COMMAND. Because of this implied object
of ANY, this meta-COMMAND would be considered for any of the following
player inputs:
BREAK LOCK
BREAK THE LOCK WITH MACE
BREAK LOCK WITH THE LARGE SWORD
BREAK LOCK WITH ROCK (will not produced desired result)
BREAK LOCK WITH DWARF'S HEAD (will not produced desired result)
If the COMMAND is an ANY meta-command, the word ANY will be the only word
follow the word COMMAND. The end of the meta-command is signalled by
END_COMMAND on a separate line.
Between COMMAND and END_COMMAND are a series of conditional tests and
actions to be performed. Each condition or action appears on a separate
line. The first word of the action or condition line is the "Token", or
abbreviation for the action or condition. AGT allows 208 such tokens.
These tokens are a short-hand description of what condition is being tested
or what action is to be performed. The tokens are normally shown with each
of the separate words of the short-hand description capitalized, e.g.
PrintMessage. This is only for better readability. Internally, AGT does
not distinguish between upper and lower case in tokens.
There may be several parameters on the line following the token. The
number of parameters varies from none to two depending upon the specific
token. For example, the token "KillPlayer" has no numerical parameters;
the token "PrintMessage" requires one parameter (i.e., the label for the
message to be printed); the token "SwapLocations" requires two parameters
(i.e., the two item labels of the items to have their locations switched).
Following the parameters (if any) on the line is space for comments. It is
recommended that meta-commends be very well commented and that the comments
be written as the meta-commands are first written. Don't try to document
them afterwards -- because you'll never get around to really doing it! For
added clarity, comments should be set off by some type of delimiter, such
as, "(*", "*)" or "{", "}" or a preceding ";".
If a conditional token is preceded on the line with the word "NOT", the
sense of the conditional test is reversed, i.e., NOT InRoom [Evil Wizard]
tests that creature [Evil Wizard] is NOT in the current room.
The token OR may be used to connect two or more separate conditional tests
within a meta-command. The overall test will be TRUE if any of the
individual OR conditions is TRUE. In the above example, the sequence
68
IsCarrying [Battle Axe]
OR
Present [Sword]
VariableGT [Strength] 90 ; Player has enough strength to swing sword
FlagON [Sword has been pulled free from stone]
OR
IsCarrying [Iron Mace]
VariableGT [Strength] 50 ; Player has enough strength to swing mace
tests if the player is carrying or has access to one (or more) of the heavy
weapons which is capable of breaking the lock on the door.
If there isn't an OR token between two conditions, there is an implied AND
condition between successive conditions. The end of the series of OR's is
determined when AGT encounters the first Action token following the first
OR. For example, the above meta-command might be rewritten in
pseudo-PASCAL as:
IF (Verb = 'BREAK') AND (Noun = 'LOCK') THEN {"BREAK LOCK"}
IF InRoom([locked oak door]) THEN {Locked oak door is here}
IF (NOT InRoom([Evil Wizard])) THEN {Evil Wizard not here}
IF IsCarrying([Battle Axe]) {Player has means to break door}
OR (Present([Sword]) AND (Variable[Strength] > 90)
AND FlagON[Sword has been pulled free from stone]))
OR (IsCarrying(Iron Mace) AND (Variable[[Strength]] > 50))
THEN BEGIN
SwapLocations([locked oak door],[open doorway]);
PrintMessage([Your blows break the lock and door swings
open]); {Print appropriate message}
ChangePassageway([North],{throne room]); {Open way north}
DoneWithTurn := TRUE; {Nothing more for this turn}
END;
When processing a meta-command, AGT starts at the first action or condition
and continues to process each token until one of the conditions within the
meta-command is not met, i.e., it is FALSE, then AGT skips to the next
meta-command within the .AGT file. For example, consider the following:
COMMAND ANY
Present [Blazing torch]
CounterGT [Torch counter] 75
; Torch has been lit for at least 75 turns
PrintMessage [Your torch is flickering and growing weaker]
CounterEquals [Torch counter] 100
; Torch has been lit for 100 turns
PrintMessage [The torch finally goes out!]
TurnCounterOFF [torch counter]
; Torch has gone out, so turn torch counter OFF
SwapLocations [Blazing torch] [unlit torch]
END_COMMAND
69
In this meta-command, Counter [Torch counter] is used to keep track of the
number of turns that the torch has been blazing. If the blazing torch
isn't being carried by the player or in the current room, the very first
condition is FALSE and AGT would skip ahead to the next meta-command --
i.e., no further tokens in this meta-command would be considered. However,
if the blazing torch was present in the room, AGT would consider the second
condition, specifically, if the torch has been blazing for more than 75
turns. If it has, then the next token would cause message [Your torch is
flickering and growing weaker] to be printed. Then the next token would
test if the torch has been blazing for exactly 100 turns. If it hasn't,
then AGT skips ahead to the next meta-command in the .AGT file. If the
torch has been blazing for exactly 100 turns, then the last three tokens
(all action tokens) are processed and the message [The torch finally goes
out!] is printed, the blazing torch counter is turned OFF, and an [unlit
torch] is swapped for the [blazing torch]. For example, the above
meta-command might be rewritten in pseudo-PASCAL:
IF (Verb = 'ANY') THEN {ANY and ALL commands}
IF Present([Blazing torch]) THEN
IF (Counter[Torch counter] > 75) THEN
{Burning for more than 75 turns}
BEGIN
PrintMessage([The torch is growing weaker.]);
IF (Counter[Torch counter] = 100)
{Burning exactly 100 turns}
THEN BEGIN
PrintMessage([The torch finally goes out!]);
TurnCounterOFF([Torch counter]); {Turn burn counter off}
SwapLocations([Blazing Torch],[unlit torch]);
END;
END;
PRINTING SHORT MESSAGES FROM META-COMMANDS
MCOMPILE provides a short-cut for printing simple messages from within
meta- commands: simply put the message in quotation marks following the
PrintMessage token; no label is necessary. Consider this example:
COMMAND FIRE PHASER
IsCarrying [phaser]
VariableEquals [phaser shots] 0
PrintMessage [phaser empty]
END_COMMAND
MESSAGE [phaser empty]
The phaser is out of energy.
END_MESSAGE
The message short-cut allows the game designer to abbreviate this command
as follows:
70
COMMAND FIRE PHASER
IsCarrying [phaser]
VariableEquals [phaser shots] 0
PrintMessage "The phaser is out of energy."
END_COMMAND
MCOMPILE will translate the quoted text following the PrintMessage token
into a message number, and create a corresponding message definition in the
.AGT file.
MCOMPILE searches for the quotation marks "from the outside in," so
messages that require quote marks as part of the text are possible:
PrintMessage "This message has "quotation marks" in it."
PrintMessage ""Aye, aye, sir.""
The first and last quotes are removed from the message; all others are left
intact. (If you find these "nested" quotes confusing or undesirable, you
can change the short-cut message delimiter characters.)
If no closing quote is found, an error message will be generated by
MCOMPILE.
Of course, if the message itself contains quote marks, then a closing
message delimiter must be supplied to mark the end of the message --
otherwise the last quote mark would signal the end of the text. For
example:
PrintMessage "This message has "embedded" quotes.
Without a closing quote, this message would be printed as follows:
This message has "embedded
and MCOMPILE would assume the remaining text on the line was a comment.
Naturally, the above short-cut message style is not appropriate for
messages which can be printed from more than one meta-command. For short,
specialized messages, however, this style can eliminate a lot of typing and
reduce the size of the .AGT file.
MULTI-LINE SHORT-CUT MESSAGES
Multi-line short-cut messages can be written by putting the PrintMessage
token on a line by itself and terminating the text with END_PrintMessage:
71
COMMAND ANY
Present [adderzag]
Chance 35
PrintMessage
The adderzag hesitates for a fraction of an eyeblink, then lunges at
you. You try to dodge the horrible mass of evil flying at your heart,
but you slip on the ice and lose your balance. The 'zag crashes into
your chest and you both go sliding across the frozen ground.
END_PrintMessage
...
END_COMMAND
Notice that MCOMPILE tells the difference between single and multi-line
messages by the presence or absence of text following the PrintMessage
keyword; do not put anything on the same line as the keyword when using
this format.
Multi-line short-cut messages may contain as many lines of text as
necessary, and may freely use quotation marks.
Because a short-cut message can only be used by one meta-command, you will
still need to manually create MESSAGE definitions for messages used by
multiple meta-commands.
META-COMMANDS CONDITIONAL TESTS
The are a total of 106 separate condition tokens in AGT. Since each of
this conditions may be prefaced by a NOT condition, there are actually a
total of 212 conditional tests possible within a meta-command. These
conditional tests divide into several logical groups:
- Tests about the player's status and/or condition
- Tests about the status/condition of specific item(s)
- Tests about the status/condition of the current NOUN
- Other miscellaneous tests
Let's consider each of these logical groups in order. First, tests about
the player's status and/or Condition:
72
┌────────────────────┐
╔════════════════════════╡ PLAYER CONDITIONS ╞═══════════════════════════════╗
║ └────────────────────┘ ║
║ NUMBER/TYPES ║
║ TOKEN NAME OF PARAMETERS EXPLANATION ║
╠═════════════════════╤═╤═══════════╤═════════════════════════════════════════╣
║ AtLocation │1│Location │ Player is located at room Location ║
║ AtLocationGT │1│Location │ Player is in room greater than Location ║
║ AtLocationLT │1│Location │ Player is in room less than Location ║
║ FirstVisitToRoom │0│None │ First visit to current room ║
║ IsCarryingSomething │0│None │ Player is carrying something ║
║ IsCarryingNothing │0│None │ Player is carrying nothing ║
║ IsCarryingTreasure │1│Points# │ Player is carrying at least one item ║
║ │ │ │ that is worth at least Points# ║
║ IsWearingSomething │0│None │ Player is wearing something ║
║ IsWearingNothing │0│None │ Player is wearing nothing ║
║ LoadWeightEquals │1│Number │ Player's load weighs equals Number ║
║ LoadWeightGT │1│Number │ Player's load weighs more than Number ║
║ LoadWeightLT │1│Number │ Player's load weighs less than Number ║
║ NewLife │0│None │ Player has just been resurrected or ║
║ │ │ │ start of game ║
╚═════════════════════╧═╧═══════════╧═════════════════════════════════════════╝
All these tokens test conditions about the player current status, i.e.,
where he is/isn't located, if he is/isn't wearing or carrying something,
and if his current load weighs a certain amount. All these conditions
are obvious except for
IsCarryingTreasure 10 ; Has something worth at least 10 points
which might be used to test whether it is appropriate to have some type
of thief (randomly) rob the player of his valuables.
The second group of conditions test the status of various items or
nouns:
73
┌────────────────────┐
╔════════════════════════╡ ITEM(S) CONDITIONS ╞═══════════════════════════════╗
║ └────────────────────┘ ║
║ NUMBER/TYPES ║
║ TOKEN NAME OF PARAMETERS EXPLANATION ║
╠═════════════════════╤═╤═══════════╤═════════════════════════════════════════╣
║ Present │1│Item# │ Item# is in room, carried or worn ║
║ IsWearing │1│Item# │ Item# is being worn ║
║ IsCarrying │1│Item# │ Item# is being carried ║
║ IsNowhere │1│Item# │ Item# is located NOWHERE (in room 0) ║
║ IsSomewhere │1│Item# │ Item# is located somewhere (not in 0) ║
║ InRoom │1│Item# │ Item# is located in current room ║
║ IsLocated │2│Item# Loc │ Item# is located in room Location ║
║ Together │2│Itm1# Itm2#│ Itm1# and Itm2# are in same place ║
║ IsON │1│Item# │ Item# is ON ║
║ IsOFF │1│Item# │ Item# is OFF ║
║ IsOpen │1│Item# │ Item# is Open ║
║ IsClosed │1│Item# │ Item# is Closed ║
║ IsLocked │1│Item# │ Item# is Locked ║
║ IsUnLocked │1│Item# │ Item# is UnLocked ║
║ IsEdible │1│Item# │ Item# is Edible ║
║ IsDrinkable │1│Item# │ Item# is Drinkable ║
║ IsPoisonous │1│Item# │ Item# is Poisonous ║
║ IsMovable │1│Item# │ Item# is Movable ║
║ IsGroupMember │1│Item# │ Item# is a member of the group ║
║ SomethingInside │1│Item# │ Item# has something inside it. Item# ║
║ │ │ │ can represent a ROOM, NOUN or CREATURE║
╚═════════════════════╧═╧═══════════╧═════════════════════════════════════════╝
All but two of the above tokens require one parameter: the number of the
item for which the conditional test is being considered. Examples of
these two exceptions are:
IsLocated [axe] [storeroom]
Together [right glove] [left glove]
The next group of conditional tokens is similar to the above except that
they are tests for the current NOUN which has been input, not a specific
item:
74
┌────────────────────┐
╔════════════════════════╡ NOUN CONDITIONS ╞═══════════════════════════════╗
║ └────────────────────┘ ║
║ NUMBER/TYPES ║
║ TOKEN NAME OF PARAMETERS EXPLANATION ║
╠═════════════════════╤═╤═══════════╤═════════════════════════════════════════╣
║ NOUNPresent │0│None │ NOUN is in room, carried or worn ║
║ NOUNIsWearing │0│None │ NOUN is being worn ║
║ NOUNIsCarrying │0│None │ NOUN is being carried ║
║ NOUNIsNowhere │0│None │ NOUN is located NOWHERE (in room 0) ║
║ NOUNIsSomewhere │0│None │ NOUN is located somewhere (not room 0) ║
║ NOUNInRoom │0│None │ NOUN is located in current room ║
║ NOUNIsLocated │1│Location │ NOUN is located in room Location ║
║ NOUNIsON │0│None │ NOUN is ON ║
║ NOUNIsOFF │0│None │ NOUN is OFF ║
║ NOUNIsOpen │0│None │ NOUN is Open ║
║ NOUNIsClosed │0│None │ NOUN is Closed ║
║ NOUNIsLocked │0│None │ NOUN is Locked ║
║ NOUNIsUnLocked │0│None │ NOUN is UnLocked ║
║ NOUNIsEdible │0│None │ NOUN is Edible ║
║ NOUNIsDrinkable │0│None │ NOUN is Drinkable ║
║ NOUNIsPoisonous │0│None │ NOUN is Poisonous ║
║ NOUNIsMovable │0│None │ NOUN is Movable ║
║ NOUNpointsEquals │1│Number │ NOUN's points equal Number ║
║ NOUNpointsGT │1│Number │ NOUN's points are greater than Number ║
║ NOUNpointsLT │1│Number │ NOUN's points are less than Number ║
║ NOUNweightEquals │1│Number │ NOUN's weight equals Number ║
║ NOUNweightGT │1│Number │ NOUN's weight is greater than Number ║
║ NOUNweightLT │1│Number │ NOUN's weight is less than Number ║
║ NOUNIsCreature │0│None │ NOUN is a creature, rather than Noun ║
║ NOUNIsNumber │1│Number │ NOUN's num is Number, e.g., NOUN is ║
║ │ │ │ number ║
╚═════════════════════╧═╧═══════════╧═════════════════════════════════════════╝
The above tokens are especially useful if the game designer wants to
create his own unique standard default responses to situations, rather
than relying on the normal AGT responses. For example, below are new
default responses for the verb GET:
COMMAND GET ANY
NOUNInRoom ; the NOUN is in current room
NOUNIsMovable ; the NOUN can be moved
LoadWeightLT 90 ; player is carrying less than 90 pounds
NOUNweightLT 11 ; the NOUN is less than 11 pounds
GetNOUN ; Add NOUN to items being carried
PrintMessage [You add the $noun$ to your load.]
DoneWithTurn ; Nothing more required for this turn
END_COMMAND
75
COMMAND GET ANY
NOUNIsCarrying ; the NOUN is currently being carried
PrintMessage [You already have it, Stupid!]
DoneWithTurn ; Nothing more required for this turn
END_COMMAND
COMMAND GET ANY
NOT NOUNPresent ; the NOUN is NOT present
PrintMessage [The $noun$ isn't here, you oaf!]
DoneWithTurn ; Nothing more required for this turn
END_COMMAND
COMMAND GET ANY
NOT NOUNIsMovable [NOUN cannot be moved]
PrintMessage [Sorry, but the $noun$ cannot be moved!]
DoneWithTurn ; Nothing more required for this turn
END_COMMAND
COMMAND GET ANY
NOUNIsMovable ; the NOUN can be moved
LoadWeightGT 89 ; player is carrying 90 pounds or more already
PrintMessage [Your load is too heavy to carry the $noun$.]
DoneWithTurn ; Nothing more required for this turn
END_COMMAND
A series of COMMANDS like these is processed sequentially by their order
of appearance in the .AGT file. As a result, the COMMANDs order is very
important! For example, if the player gave the input GET STATUE and the
statue was not in the room and was also not movable, the error message
"The statue isn't here, you oaf!" would be printed rather than "Sorry,
but the statue cannot be moved!" because of the order of their
respective COMMANDS above (or in the .AGT file).
The last group of conditional tokens is a catch-all:
76
┌────────────────────────────┐
╔════════════════════╡ MISCELLANEOUS CONDITIONS ╞═══════════════════════════╗
║ └────────────────────────────┘ ║
║ NUMBER/TYPES ║
║ TOKEN NAME OF PARAMETERS EXPLANATION ║
╠═════════════════════╤═╤═══════════╤═════════════════════════════════════════╣
║ NamePresent │0│None │ Addressee is present in current room ║
║ NameIsNumber │1│Number │ Addressee is Creature or Noun number ║
║ ObjectPresent │0│None │ Object is present ║
║ ObjectIsCreature │0│None │ Object is a Creature ║
║ ObjectIsNumber │1│Number │ Object is Creature or Noun number ║
║ LightPresent │0│None │ Current room has necessary light ║
║ RoomNeedsLight │0│None │ Current room needs a light ║
║ FlagON │1│Flag# │ Flag# is ON ║
║ FlagOFF │1│Flag# │ Flag# is OFF ║
║ ScoreEquals │1│Number │ Current score is equal to Number ║
║ ScoreGT │1│Number │ Score is greater than Number ║
║ ScoreLT │1│Number │ Score is less than Number ║
║ NumberEquals │1│Number │ Number input is equal to Number ║
║ NumberGT │1│Number │ Number is greater than Number ║
║ NumberLT │1│Number │ Number is less than Number ║
║ AnswerIsCorrect │0│None │ Last answer was correct ║
║ AnswerIsWrong │0│None │ Last answer was wrong ║
║ TurnsEquals │1│Number │ Number of turns is equal to Number ║
║ TurnsGT │1│Number │ Number of turns is greater than Number ║
║ TurnsLT │1│Number │ Number of turns is less than Number ║
║ CounterEquals │2│Ctr# Number│ Counter# is equal to Number ║
║ CounterGT │2│Ctr# Number│ Counter# is greater than Number ║
║ CounterLT │2│Ctr# Number│ Counter# is less than Number ║
║ VariableEquals │2│Var# Number│ Variable# is equal to Number ║
║ VariableGT │2│Var# Number│ Variable# is greater than Number ║
║ VariableLT │2│Var# Number│ Variable# is less than Number ║
║ CompareVariables │2│Var#1 Var#2│ Variable#1 is less than Variable#2 ║
║ VariableChance │2│Var# Number│ Variable# is less than a random number ║
║ │ │ │ from 1 to Number ║
║ Chance │1│Percent │ Odds percent, i.e., 10 % chance of TRUE ║
║ PromptForYES │0│None │ Prompts for Y or N -- TRUE if Yes ║
║ PromptForNO │0│None │ Prompts for Y or N -- TRUE if No ║
║ VerbIsDirection │0│None │ Verb is movement or direction ║
╚═════════════════════╧═╧═══════════╧═════════════════════════════════════════╝
Just a few words of explanation about a couple of these. PromptForYES
and PromptForNO cause the player to be queried and to respond by
entering a YES (or Y) or NO (or N) on the keyboard. These conditions
are then TRUE or FALSE depending upon the what is entered. These tokens
are particular useful when you want to ask the player a question that
requires a YES or NO answer like whether he would like a hint.
AnswerIsCorrect and AnswerIsWrong are similar tokens for asking
questions which do not have YES and NO answers like asking a riddle. An
example of how to ask a trivia question will be given later in this
document.
77
The number referenced by the NumberEquals, NumberGT and NumberLT is a
number that the player inputs via the keyboard in response to a
GetNumberInput action token. An example of this sequence of events will
be given later.
The game designer has 255 Flags (1 to 255) which can be tested for being
ON or OFF respectively by the FlagON and FlagOFF tokens. There are 50
Counters (1 to 50) and 50 Variables (1 to 50) which can also be tested
by various tokens described above. How to "define" the labels for
flags, counters and variables will be described in the below. How to
set these Flags, Counters and Variables will be described in the section
on ACTION tokens that follows.
The master's Edition allows you to define these things using labels as
follows in your .AGT file:
FLAG [label]
COUNTER [label]
VARIABLE [label]
QUESTION [label]
Each of these keywords (i.e., FLAG, COUNTER, etc.) appears on its own
line, anywhere in the file. They do not have any effect on the
structure of the game, but simply tell MCOMPILE what type of item the
label refers to. For example:
FLAG [flashlight lit]
VARIABLE [energy left]
...
COMMAND ANY
Present [flashlight]
FlagON [flashlight lit]
VariableLT [energy left] 20
END_COMMAND
MESSAGE [batteries dying]
Your batteries will last only #VAR[energy left]# more turns.
END_MESSAGE
These keywords cause the labels to be defined with the next available
number for the particular item. For example, if there were already four
other variables defined, MCOMPILE would assign the value 5 to the label
[energy left] upon encountering the VARIABLE definition.
TEXT MACROS
A text macro is a special kind of label that can be defined as almost
any text you choose. The format of a single-line macro definition is:
#DEFINE [label] label definition
78
This causes the label to be defined as all text after the label to the
end of the line (not including the first character after the label,
which is normally a blank). Macros are useful for constants used
throughout the game file:
#COMMENT Macros for special "rooms"
#DEFINE [Nowhere] 0
#DEFINE [Carried] 1
#DEFINE [Worn] 1000
It's sometimes handy to use a macro for something you may want to
change, so you don't have to track down every occurrence of the item
each time you change it. For example:
VARIABLE [health]
#DEFINE [max health] 100
#DEFINE [rest delay] 5
#DEFINE [rest benefit] 20
...
COMMAND REST
TimePasses
Delay [rest delay]
PrintMessage "Having rested for a while, you now feel much better."
AddToVariable [health] [rest benefit]
VariableGT [health] [max health]
SetVariableTo [health] [max health]
END_COMMAND
COMMAND REST
DoneWithTurn
END_COMMAND
This allows you to quickly change, say, the maximum health the player
can have, no matter how many times that value is referred to in the
game.
Macros are not limited to just numbers. They can contains several
words, punctuation, etc. Here's another example, adapted from the
Colossal Cave Adventure:
#DEFINE [magic word] XYZZY
...
Dummy_Verb17 [magic word]
...
79
ROOM_DESCR [debris room]
You are in a debris-filled room with stuff washed in from the
surface. A low wide passage with cobbles becomes plugged with mud
and debris here, but an awkward canyon leads upward and west. A
note on the wall says:
Magic Word "[magic word]"
END_ROOM_DESCR
...
COMMAND [magic word]
FlagOFF [cave closed]
AtLocation [debris room]
PrintMessage [transported]
GoToRoom [inside building]
DoneWithTurn
END_COMMAND
...
COMMAND [magic word]
FlagOFF [cave closed]
AtLocation [inside building]
PrintMessage [transported]
GoToRoom [debris room]
DoneWithTurn
END_COMMAND
...
COMMAND [magic word]
PrintMessage "A voice booms out, "That word doesn't work here!""
DoneWithTurn
END_COMMAND
MACRO NESTING AND RECURSION
By default, macros are "nestable", meaning that they can include
references to other labels. When a macro is expanded, the resulting
text is then scanned for additional macros and labels. The following
example makes use of macro nesting:
NOUN [burning torch]
...
NOUN [unlit torch]
...
#DEFINE [extinguish] SwapLocations [burning torch] [unlit torch]
...
80
COMMAND ANY
FlagON [wind blowing]
Chance 10
PrintMessage "The wind blows out your torch."
[extinguish]
END_COMMAND
The danger with nestable labels is this: if a macro refers to itself,
either directly or indirectly, then the macro's final value cannot be
determined. MCOMPILE would spend eternity trying to expand the macro,
forever ending up with another macro. For example:
#DEFINE [yoyo] xx [yoyo] xx
MCOMPILE will define a macro called [yoyo] with the text "xx [yoyo] xx".
When the macro is expanded, a new macro (also called [yoyo]) is
discovered which must itself expanded, ad infinitum. Here's another
example, using indirect recursion:
#DEFINE [tweedle dee] [tweedle dum]
#DEFINE [tweedle dum] [tweedle dee]
Since macros are not expanded until the second phase of MCOMPILE's
operation, they may not include any text which MCOMPILE requires during
its first phase. Specifically, macros may not contain any of the
following keywords:
ROOM, ROOM_DESCR
NOUN, NOUN_DESCR
CREATURE, CREATURE_DESCR
PUSH_DESCR, PULL_DESCR, TURN_DESCR, PLAY_DESCR
TEXT, MESSAGE, QUESTION
FLAG, COUNTER, VARIABLE
STANDARD, VOCABULARY
END_keyword
#DEFINE, #INCLUDE, #OPTIONS, #COMMENT, #END_COMMENT
unless, of course, such text is intended as game output rather than
keywords. In other words, if you needed a word like ROOM or #INCLUDE at
the beginning of a line in a text description, it would be allowable
(and possibly necessary) to define such text as a macro.
MCOMPILE allows up to 500 macros per adventure game, independent of the
number of other labels in the file.
MULTIPLE SOURCE FILES
It is sometimes inconvenient (or impossible) to use a single source file
for an adventure game. For example, your game may grow until it is too
large for your text editor to handle. Or you may have a group of macros
or meta-commands that you'd like to use in more than one adventure game.
81
For this purpose, MCOMPILE provides the #INCLUDE directive, which causes
another source file to be read in and processed as if it was part of the
main file. For example, if MYGAME.AGT contains these lines:
ROOM_DESCR [throne room]
#INCLUDE throne.agt
END_DESCR
and THRONE.AGT contains these lines:
You are in a shambled throne room. Rows of stone statues on either
side of the great hall seem to hold a mute vigil, awaiting the
return of their sovereign.
then MCOMPILE will process MYGAME.AGT as if it looked like this:
ROOM_DESCR [throne room]
You are in a shambled throne room. Rows of stone statues on either
side of the great hall seem to hold a mute vigil, awaiting the
return of their sovereign.
END_DESCR
For your convenience there is a standard definitions file called
STDDEFS.AGT that contains some helpful macros. If your source file
contains the line
#INCLUDE stddefs.agt
then the following defined labels will be available for your use:
#COMMENT Special "rooms"
#DEFINE [Nowhere] 0
#DEFINE [Carried] 1
#DEFINE [Worn] 1000
#COMMENT Special "nouns"
#DEFINE [Nothing] 0
#DEFINE [Any Light] 1
#COMMENT Special "flags"
#DEFINE [Debug] 0
#COMMENT macros for the directions used with ChangePassageway
#DEFINE [North] 1
#DEFINE [South] 2
#DEFINE [East] 3
#DEFINE [West] 4
#DEFINE [NorthEast] 5
#DEFINE [NorthWest] 6
#DEFINE [SouthEast] 7
#DEFINE [SouthWest] 8
#DEFINE [Up] 9
82
#DEFINE [Down] 10
#DEFINE [Enter] 11
#DEFINE [Exit] 12
Be careful with the names of your include files. It is wise to avoid
giving these files names with extensions of .AGT, .TTL, etc. For
example, don't try anything like this:
#COMMENT mygame.agt
TITLE
#INCLUDE mygame.ttl
END_TITLE
The presence of the TITLE keyword in the .AGT file would cause the .TTL
file to be destroyed, since MCOMPILE would try to create the title file
itself.
Included files may include other files, up to a maximum of two levels
deep.
OTHER MCOMPILE KEYWORDS
To identify the text for the game title, instructions and /or
vocabulary, MCOMPILE provides some additional keywords:
TITLE
The game title goes here, in the .TTL file format.
END_TITLE
INSTRUCTIONS
The game instructions go here, in the .INS file format.
END_INSTRUCTIONS
VOCABULARY
The game vocabulary goes here, in the .VOC file format.
END_VOCABULARY
When one of these keywords is found, MCOMPILE creates the appropriate
file and writes the information (without the keywords) to the file. If
any of these are omitted, MCOMPILE will ignore the corresponding file to
allow you to maintain it manually.
DELIMITER CHARACTERS
The default delimiters for labels are the braces, i.e., [ and ], the
delimiters for short-cut messages are the quote marks, i.e., " and ".
If you wish to change delimiters, you can use the #OPTIONS command
within your source file as follows:
83
#OPTIONS Labels{} Messages()
For example, the above would change the default delimiters for labels to
curly braces, i.e., { and }, the delimiters for short-cut messages to
the opening and closing parentheses.
META-COMMANDS ACTION TOKENS
There are a total of 102 separate action tokens in AGT. These actions
divide into several logical groups:
- Actions involving the player
- Actions involving specific item(s), the NOUN or locations
- Other miscellaneous actions
Let's consider each of these logical groups in order. First, actions
involving the player:
┌────────────────────────┐
╔═══════════════════════╡ PLAYER ACTION TOKENS ╞════════════════════════════╗
║ └────────────────────────┘ ║
║ NUMBER/TYPES ║
║ TOKEN NAME OF PARAMETERS EXPLANATION ║
╠═════════════════════╤═╤═══════════╤═════════════════════════════════════════╣
║ GoToRoom │1│Location# │ Send player to Location# ║
║ GoToRandomRoom │2│Loc#1 Loc#2│ Randomly pick a room between Loc#1 and ║
║ │ │ │ Loc#2 and send player to it ║
║ GetIt │1│Item# │ Item# is now being carried ║
║ WearIt │1│Item# │ Item# is now being worn ║
║ DropIt │1│Item# │ Drop Item# into current room ║
║ RemoveIt │1│Item# │ Remove Item# and drop into room ║
║ GetNOUN │0│None │ NOUN is now being carried ║
║ WearNOUN │0│None │ NOUN is now being worn ║
║ DropNOUN │0│None │ Drop NOUN into current room ║
║ RemoveNOUN │0│None │ Remove NOUN and drop into room ║
║ DropEverything │0│None │ Drop all items being carried ║
║ RemoveEverything │0│None │ Remove all items being worn ║
║ KillPlayer │0│None │ Make player dead at end of turn ║
╚═════════════════════╧═╧═══════════╧═════════════════════════════════════════╝
These actions are all straight-forward.
A WORD OF WARNING:
When AGT encounters and processes an action token, it is done without
fanfare or logical checking. For example, if the actions
DropIt [Rubber Ducky] ; Put the Rubber Ducky in the room
WearNOUN ; Put on or Wear NOUN
84
are encountered, they are done without checking whether the player is
carrying the Rubber Ducky currently or if the NOUN is something that
might be logically worn. The game designer is warned that this kind of
logical checking before taking actions is his or her responsibility --
not AGT's!
The second group of actions involve items, nouns and locations:
┌────────────────────────────────────┐
╔═══════════════════╡ ITEM/NOUN/LOCATION ACTION TOKENS ╞════════════════════╗
║ └────────────────────────────────────┘ ║
║ NUMBER/TYPES ║
║ TOKEN NAME OF PARAMETERS EXPLANATION ║
╠═════════════════════╤═╤═══════════╤═════════════════════════════════════════╣
║ PutInCurrentRoom │1│Item# │ Put Item# in current room ║
║ PutNOUNInCurrentRoom│0│None │ Put NOUN in current room ║
║ RelocateAll │2│Loc1# Loc2#│ Relocate all items at Loc1# to Loc2# ║
║ SendToRoom │2│Item# Loc# │ Put Item# in Location Loc# ║
║ SendNOUNToRoom │1│Location# │ Put NOUN in room Location# ║
║ SendAllToRoom │1│Location# │ Send all carried items to Location# ║
║ SendTreasuresToRoom │2│Loc# Point#│ Send all carried items whose ║
║ │ │ │ points > Point# to Loc# ║
║ Destroy │1│Item# │ Item# is now NOWHERE (in room 0) ║
║ DestroyNOUN │0│None │ NOUN is now NOWHERE (in room 0) ║
║ SwapLocations │2│Itm#1 Itm#2│ Swap locations of Item#1 & Item#2 ║
║ SendToItem │2│Itm#1 Itm#2│ Put Itm#1 in location of Itm#2 ║
║ SendNOUNToItem │1│Item# │ Put NOUN in location of Item# ║
║ OpenIt │1│Item# │ Item# is now open ║
║ CloseIt │1│Item# │ Item# is now closed ║
║ LockIt │1│Item# │ Item# is now locked ║
║ UnlockIt │1│Item# │ Item# is now unlocked ║
║ OpenNOUN │0│None │ NOUN is now open ║
║ CloseNOUN │0│None │ NOUN is now closed ║
║ LockNOUN │0│None │ NOUN is now locked ║
║ UnlockNOUN │0│None │ NOUN is now unlocked ║
║ AddToGroup │1│Item# │ Adds Item# to group ║
║ RemoveFromGroup │1│Item# │ Removes Item# from group ║
║ MoveTheGroup │1│Location# │ Move group to Location# ║
╚═════════════════════╧═╧═══════════╧═════════════════════════════════════════╝
Several of these deserve some explanation. SendTreasureToRoom is useful
when the game designer wishes to have the player's current treasures or
valuables stolen or disappear. For example:
SendTreasureToRoom [Throne room] 9 ; send valuables to throne room
would cause any items that were being currently carried and had point
values of 10 or more to be sent to room [Throne room]. Items being
carried with values of 9 or less would continue to be carried. The
conditional token IsCarryingTreasure can be used to test whether such a
"theft" is appropriate.
85
The SwapLocations action token is very useful whenever the game designer
wishes to change the status or condition of an item. For example, this
action can be used to replace a closed door with an open door, or to
replace an egg with egg shell pieces (when the player gives the input
BREAK EGG), or to replace a small plant with a larger plant (when the
player inputs the command WATER PLANT), or to replace a frog with a
handsome prince (when the player inputs KISS FROG). A very useful and
powerful token!
The last group of actions do a variety of tasks:
┌─────────────────────────────────┐
╔═══════════════════╡ MISCELLANEOUS ACTION TOKENS ╞═══════════════════════╗
║ └─────────────────────────────────┘ ║
║ NUMBER/TYPES ║
║ TOKEN NAME OF PARAMETERS EXPLANATION ║
╠═════════════════════╤═╤═══════════╤═════════════════════════════════════════╣
║ ShowScore │0│None │ Show current SCORE ║
║ PlusScore │1│Number │ Add Number to current SCORE ║
║ MinusScore │1│Number │ Subtract Number from current SCORE ║
║ ShowInventory │0│None │ Show current INVENTORY ║
║ ShowContents │1│Number │ Show contents (if any) of entity Number ║
║ WaitForReturn │0│None │ Print 'Hit RETURN' message and wait ║
║ TimePasses │0│None │ Show 'Time passes...' message ║
║ Delay │1│Number │ Delay for Number seconds ║
║ ClearScreen │0│None │ Clear screen ║
║ DescribeThing │1│Number │ Describe thing Number (whatever) ║
║ LookAtRoom │0│None │ Cause a VERBOSE look at room ║
║ Tone │2│Hz Ms │ Makes a tone on speaker of Hz Hertz (440║
║ │ │ │ Hertz = A on piano) for Ms milliseconds║
║ PrintMessage │1│Number │ Print message Number in .AGT file ║
║ RandomMessage │2│Num1 Num2 │ Randomly picks a message from Num1 to ║
║ │ │ │ Num2 in .AGT file and prints it ║
║ BlankLine │0│None │ Print a blank line ║
║ GetNumberInput │2│Num1 Num2 │ Prompt for player to input a Number ║
║ │ │ │ where Num1 <= Number <= Num2. ║
║ │ │ │ If Num1=Num2, then no range will be ║
║ │ │ │ given in prompt. ║
║ AskQuestion │1│Question# │ Ask and get answer to question# ║
╚═════════════════════╧═╧═══════════╧═════════════════════════════════════════╝
86
┌────────────────────────────────────────────┐
╔══════════════╡ MISCELLANEOUS ACTION TOKENS - CONTINUED ╞═════════════════╗
║ └────────────────────────────────────────────┘ ║
║ NUMBER/TYPES ║
║ TOKEN NAME OF PARAMETERS EXPLANATION ║
╠═════════════════════╤═╤═══════════╤═════════════════════════════════════════╣
║ ChangePassageway │2│Dir# Loc# │ Create or close a passageway ║
║ │ │ │ from current_room to Loc# via Dir#. ║
║ │ │ │ Dir# = 1 = north...Dir # = 12 = exit. ║
║ │ │ │ If Loc# = 0 then closes passageway. ║
║ │ │ │ If Loc# <> 0 then opens passageway ║
║ │ │ │ to room Loc# via direction Dir#. ║
║ │ │ │ Passageways are opened or closed at ║
║ │ │ │ both ends simultaneously! ║
║ TurnFlagON │1│Flag# │ Turn Flag# ON ║
║ TurnFlagOFF │1│Flag# │ Turn Flag# OFF ║
║ ToggleFlag │1│Flag# │ Toggle Flag# ║
║ TurnCounterON │1│Counter# │ Turn Counter# ON -- sets to 1 ║
║ TurnCounterOFF │1│Counter# │ Turn Counter# OFF -- sets to 0 ║
║ SetVariableTo │2│Var# Number│ Set Variable Var# to Number ║
║ AddToVariable │2│Var# Number│ Add Number to Var# ║
║ SubtractFromVariable│2│Var# Number│ Subtract Number from Var# ║
║ AddVariables │2│Var#1 Var#2│ Add Var#2 and Var#1 and put answer ║
║ │ │ │ into Var#1 ║
║ SubtractVariables │2│Var#1 Var#2│ Subtract Var#2 from Var#1 and put answer║
║ │ │ │ into Var#1 ║
║ RandomVariable │2│Var# Number│ Set Var# to a random value between 0 and║
║ │ │ │ Number ║
║ MakeVarRoomNum │1│Var# │ Set Var# to current room number ║
║ MakeVarNounNum │1│Var# │ Set Var# to number of current noun ║
║ MakeVarObjectNum │1│Var# │ Set Var# to number of current object ║
║ GoToVariableRoom │1│Var# │ Send player to room number in Var# ║
║ SendToVariableRoom │2│Num Var# │ Send Noun number num to room number ║
║ │ │ │ in Var# ║
║ GetVariableIt │1│Var# │ Get noun number in Var# ║
║ PrintVariableMessage│1│Var# │ Print message number in Var# ║
║ NounToVariable │1│Var# │ Set Var# to literal value of noun ║
║ ObjectToVariable │1│Var# │ Set Var# to literal value of object ║
║ WinGame │0│None │ Player wins game at end of turn ║
║ EndGame │0│None │ Game ends at end of turn ║
║ QuitThisCMD │0│None │ Quit evaluating this CMD ║
║ QuitAllCMDs │0│None │ Finished with all meta-commands ║
║ DoneWithTurn │0│None │ All Done this turn -- get input next ║
║ ReDirectTo │0│None │ See explanation in manual. ║
╚═════════════════════╧═╧═══════════╧═════════════════════════════════════════╝
SPECIAL META-COMMAND SITUATIONS
There are some very powerful (and potentially confusing) actions above!
Some words of explanation and some examples are in order. Specific
topics to be covered below are: (1) Flags, (2) Counters, (3) Variables,
87
(4) Number Input, (5) Asking and Answering Questions, (6) Dealing with
Multiple Nouns with the Same Name, (7) Handling the Contents of Various
Things, (8) Opening and Closing Passageways Between Rooms, and (9) Meta-
command Redirection.
FLAGS
The game designer has 255 Flags at his disposal. They are turned on
with the TurnFlagON token, turned off with the TurnFlagOFF token and
toggled with the ToggleFlag token. They are tested with the FlagON and
FlagOFF condition tokens. The game designer should take great care in
selecting and documenting his use of Flags. Always, explain what each
Flag stands for and what the ON and OFF conditions mean in comments at
the beginning of the .AGT file! Whenever you change the condition of a
Flag explain what this new condition stands for in the game!
When the game starts, all Flags are OFF. This fact can be used to test
if certain initial actions should be taken, such as, making sure the
flashlight's batteries are fresh. When the game is SAVEd and RESTOREd
the condition of the Flags, Counters and Variables is also SAVEd and
RESTOREd.
DEBUG FLAG
There is a Flag number 0 which is used by AGT to toggle the debugging
mode of meta-commands. When Flag 0 is ON then each meta-command being
considered will be output to the screen. By giving the input command
SCRIPT you can also route this information to the printer. This
capability can be invaluable when you are trying to fathom a complex
meta-command "bug". The best way to use this capability in your game is
to define a custom verb like DEBUG in the verb synonym section of the
.AGT file and then define a meta-command like:
COMMAND DEBUG
ToggleFlag 0 ; Toggles meta-command Debug mode
DoneWithTurn ; Finished with this turn
END_COMMAND
COUNTERS
There are 50 Counters (1 to 50) in AGT that can be turned ON with the
TurnCounterON token and turned OFF with the TurnCounterOFF token. When
a counter is ON, it is automatically incremented at each turn of the
game. When a counter is OFF, it is set to zero and is not incremented.
The condition of these counters can be tested using the CounterEquals,
CounterGT and CounterLT conditional tokens. Using counters is very
useful for such things as keeping track of the number of turns (1) a
torch is lit, (2) a player has been underwater using an aqua-lung, or
(3) a time-bomb has been ticking. The value of a counter can be printed
88
in a message by using #CTR5# (to print counter number 5). The game
designer's use of Counters should be very carefully commented in the
.AGT file!
VARIABLES
There are 50 Variables (1 to 50) in AGT that can be set to a specific
value with the SetVariableTo token and added to with the AddToVariable
token and subtract from with SubtractFromVariable token. These
variables can also be set to a random value with the RandomVariable
token, and variables can be added together with the AddVariables, and
subtracted from one another using the SubtractVariables token. The
condition of these variables can be tested using the VariableEquals,
VariableGT and VariableLT and VariableChance conditional tokens. Using
variables is very useful for such things as keeping track of the number
of times (1) a player has asked for HELP, (2) a player has crossed a
certain rickety bridge, or (3) until a specific event happens (like the
cave closes or the lamp's batteries go out). Other excellent uses of
variables are to keep track of various attributes the player may have
such as Strength, Health, Charisma, etc. The value of a variable can be
printed in a message by using #VAR3# (to print variable number 3).
As an example, the following meta-commands in the .AGT file will (1)
initialize the flash batteries to last a total of 100 turns, (2)
decrement a variable for every turn the light is ON, (3) issue warnings
when the battery will last 20 turns or less, (4) "kill" the flashlight
when the batteries finally go out, (5) turn the flashlight ON and OFF
with the input commands LIGHT and EXTINGUISH.
First, the basic FLAG and VARIABLE definitions:
FLAG [game started]
FLAG [flashlight lit]
VARIABLE [batt life] ; will count down the life of the battery
#DEFINE [initial battery charge] 100
#DEFINE [battery warning level] 20
Next, the ANY commands associated with the flashlight:
COMMAND ANY
FlagOFF [game started] [First turn -- initialize Battery life]
SetVariableTo [batt life] [initial battery charge]
TurnFlagON [game started]
END_COMMAND
COMMAND ANY
FlagON [flashlight lit]
SubtractFromVariable [batt life] 1
END_COMMAND
89
COMMAND ANY
FlagON [flashlight lit]
Present [on flashlight]
VariableGT [batt life] 0
NOT VariableGT [batt life] [battery warning level]
PrintMessage
Flashlight will last only #VAR[batt life]# more turns!
END_Message
#COMMENT display the next message only once
VariableEquals [batt life] [battery warning level]
PrintMessage "You had better save your batteries!"
END_COMMAND
COMMAND ANY
FlagON [flashlight lit]
VariableEquals [batt life] 0
TurnFlagOFF [flashlight lit] [Turn it off for the last time!]
SwapLocations [on flashlight] [dead flashlight]
Present [dead flashlight] [No message unless Flashlight here]
PrintMessage "The flashlight's batteries are dead!!"
END_COMMAND
Last, the specific VERB-NOUN commands associated with the flashlight:
COMMAND LIGHT FLASHLIGHT
Present [off flashlight]
TurnFlagON [flashlight lit]
SwapLocations [off flashlight] [on flashlight]
PrintMessage "The flashlight is ON and shining brightly!"
DoneWithTurn
END_COMMAND
COMMAND LIGHT FLASHLIGHT
Present [on flashlight]
PrintMessage "The flashlight is already ON, dummy!"
DoneWithTurn
END_COMMAND
COMMAND LIGHT FLASHLIGHT
Present [dead flashlight]
PrintMessage "Sorry, but the batteries are dead!"
DoneWithTurn
END_COMMAND
COMMAND EXTINGUISH FLASHLIGHT
Present [on flashlight]
TurnFlagOFF [flashlight lit]
SwapLocations [off flashlight] [on flashlight]
PrintMessage "The flashlight is now off!"
DoneWithTurn
END_COMMAND
90
COMMAND EXTINGUISH FLASHLIGHT
Present [off flashlight]
OR
Present [dead flashlight]
PrintMessage "The flashlight is already OFF!"
DoneWithTurn
END_COMMAND
Here is another example that shows how a VARIABLE might be used to cause
different shots of a phaser firing to cause different events in a "Star
Trek" adventure:
#COMMENT
AGT "Star Trek" game excerpt -- a simple example showing a few of
the features of AGT
#END_COMMENT
FLAG [game started]
VARIABLE [phaser shots] ; remaining phaser energy
COMMAND ANY
FlagOFF [game started]
TurnFlagON [game started]
SetVariableTo [phaser shots] 10
END_COMMAND
ROOM [bridge]
Bridge
SOUTH [turbolift]
END_ROOM
ROOM_DESCR [bridge]
You are on the bridge of the Enterprise.
END_ROOM_DESCR
ROOM [turbolift]
Turbolift
NORTH [bridge]
END_ROOM
ROOM_DESCR [turbolift]
You are in the turbolift.
END_ROOM_DESCR
91
NOUN [phaser]
Phaser
Hand
There is a hand phaser here.
LOCATION [bridge]
CAN_SHOOT
NUM_SHOTS 10 ; not used; we control this with meta-commands
SIZE 2
END_NOUN
NOUN_DESCR [phaser]
This is a standard box-shaped Phaser I. While not as powerful as
the pistol-shaped Phaser II, it is considerably more compact and
thus easily concealed.
END_NOUN_DESCR
COMMAND FIRE PHASER
IsCarrying [phaser]
VariableEquals [phaser shots] 0
PrintMessage "The phaser is out of energy."
DoneWithTurn
END_COMMAND
COMMAND FIRE PHASER
AtLocation [bridge]
IsCarrying [phaser]
SubtractFromVariable [phaser shots] 1
RandomMessage [fire phaser #1] [fire phaser #3]
EndGame
END_COMMAND
MESSAGE [fire phaser #1]
You level the phaser at the viewscreen and twist the dial to
"KILL".
Fortunately, Spock's telepathic powers sense the sudden insanity
gnawing at your mind, and before you know what's happening you feel
his familiar grip on your shoulder and you crumble to the floor.
You
will be relieved of command until McCoy can straighten you out.
END_MESSAGE
MESSAGE [fire phaser #2]
You press the trigger, but nothing happens. For a moment you stare
at the phaser, puzzling over the acute pain in your thumb. Then
you
remember that this is a prototype Scotty has been working on,
designed
to foil an enemy who has stolen it. It's been modified to inject a
lethal dose of tricordrazine into the hand of the firer if it is
used
on the Enterprise.
END_MESSAGE
92
MESSAGE [fire phaser #3]
You fire the phaser. The bridge wall is ruptured, and the area
rapidly depressurizes. You are killed, along with the rest of the
bridge crew.
END_MESSAGE
Needless to say, the game designer's use of Variables should be very
carefully commented in your .AGT file!
NUMBER INPUT
By using meta-commands it is possible to accept number input from the
player during the course of the game and to test the number he has
input. An example of where such a capability might be appropriate is
having the player open a combination safe. An example of use,
GetNumberInput 4 20 would cause the player to be prompted as follows:
"What number (from 4 to 20) ? "
This prompt would be repeated until the player entered a number in the
correct range (i.e., an integer from 4 to 20). If the game designer
didn't want to limit the input number to a specific range, both
parameters should be equal. For example, GetNumberInput 0 0 would cause
the prompt to be:
"What number ? "
Once input, the number can be tested by using the NumberEquals,
NumberGT, and NumberLT conditional tokens.
Another way that AGT will allow number input is as the Noun or Object
within an input command. For example, let's say the player is in an
elevator and he needs to push a button corresponding to a floor.
Commands like "PUSH 3" will be accepted by the AGT parser. The Noun "3"
can then be assigned to a variable using the NounToVariable token,
tested using the VariableEquals token, then the player would be sent to
the appropriate floor. For example, the following series of meta-
commands will enable the player to go to any one of four floors by
giving the correct command.
VARIABLE [Floor Pushed]
COMMAND PUSH ANY
SetVariableTo [Floor Pushed] 0 ; Set to 0 to start
AtLocation [In Elevator]
NounToVariable [Floor Pushed] ; get floor number, if any
VariableEquals [Floor Pushed] 1 ; Did player push 1?
GoToRoom [1st floor]
PrintMessage [The Elevator glides to #VAR2# and you exit.]
DoneWithTurn ; Finished with this turn
END_COMMAND
93
COMMAND PUSH ANY
AtLocation [In Elevator]
VariableEquals [Floor Pushed] 2 ; Did player push 2?
GoToRoom [2nd floor]
PrintMessage [The Elevator glides to #VAR2# and you exit.]
DoneWithTurn ; Finished with this turn
END_COMMAND
COMMAND PUSH ANY
AtLocation [In Elevator]
VariableEquals [Floor Pushed] 3 ; Did player push 3?
GoToRoom [3rd floor]
PrintMessage [The Elevator glides to #VAR2# and you exit.]
DoneWithTurn ; Finished with this turn
END_COMMAND
COMMAND PUSH ANY
AtLocation [In Elevator]
VariableEquals [Floor Pushed] 4 ; Did player push 4?
GoToRoom [4th floor]
PrintMessage [The Elevator glides to #VAR2# and you exit.]
DoneWithTurn ; Finished with this turn
END_COMMAND
COMMAND PUSH ANY
AtLocation [In Elevator]
NOT VariableEquals [Floor Pushed] 0 ; Did player push a number?
PrintMessage [This Elevator only has four floors.]
DoneWithTurn ; Finished with this turn
END_COMMAND
ASKING AND ANSWERING QUESTIONS
Asking and answering questions can be handled by using several
meta-commands. For example, let's assume we want to ask the trivia
question "What is the largest human organ?" to which the correct answer
is "skin". We would specify the question and answer in the .AGT file as
follows:
#DEFINE [About largest organ]
FLAG [Temporary Flag]
QUESTION [About largest organ] WHAT IS THE LARGEST HUMAN ORGAN?
ANSWER [About largest organ] SKIN
Then the following meta-commands would ask the question and give an
appropriate response based on whether the answer given was right or
wrong:
94
COMMAND Verb Noun or ANY
various conditions
AskQuestion [About largest organ]
TurnFlagON [Temporary Flag]
AnswerIsCorrect ; tests if answer is correct
TurnFlagOFF [Temporary Flag] ; off if answer right
PrintMessage [Fantastic, you got it right!!]
PlusScore 10 ; Give player 10 points for correct answer
DoneWithTurn
END_COMMAND
COMMAND Same Verb Noun or ANY
FlagON [Temporary Flag] ; not turned off in previous COMMAND
TurnFlagOFF [Temporary Flag] ; so, turn temporary flag off now
PrintMessage [Sorry, you got it wrong!!]
DoneWithTurn
END_COMMAND
When a question is asked and a response is given, the correct answer is
matched against the response by looking for the answer anywhere in the
response. This means that any of the following responses would be
considered correct by AGT:
SKIN
I THINK THE ANSWER IS SKIN
THE CORRECT RESPONSE IS "SKIN"
ANYONE KNOWS IT IS SKIN, YOU TURKEY COMPUTER!
The game designer can have up to 25 sets of questions and answers (1 to
25) in the .AGT file. They could form the basis for a series of riddles
that must be answered during the course of the adventure in order to get
all the points and win the game.
DEALING WITH MULTIPLE NOUNS WITH THE SAME NAME
Occasionally, the game designer will have to deal with the situation
where there are multiple nouns in the current room with the same name.
There are several meta-command tokens that have been specifically
developed to help deal with this situation. The first two are:
NOUNIsNumber [label] -- will test whether the NOUN in the player's
current input command is NOUN [label] and return a TRUE condition
if the noun's number was num and a FALSE condition otherwise.
ObjectIsNumber [label] -- will perform a similar test on the OBJECT
in the player's current input command.
These two meta-command tokens will be useful whenever the game has a
variety of nouns and objects with the same name and the game designer
only wants to allow certain actions to occur when specific nouns and/or
objects are used in the player's input command. For example, let's
95
consider a scenario where there are multiple "drawers" and multiple
"keys" -- potentially all in the same room -- and we want the [brass
key] to break whenever it is used to unlock the [middle drawer]. This
could be done using these two tokens as follows:
COMMAND UNLOCK DRAWER WITH KEY
Present [Brass key]
Present [Middle drawer]
NOUNIsNumber [Middle Drawer] ; The middle drawer was specified
ObjectIsNumber [Brass key] ; was also specified in input
SwapLocations [Brass Key] [Broken key]
PrintMessage [The key broke in the lock]
UnLockIt [Middle drawer]
DoneWithTurn
END_COMMAND
HANDLING THE CONTENTS OF VARIOUS THINGS
AGT has two meta-command tokens that are extremely useful whenever you
needed to deal with the contents of ROOMs, NOUNs or CREATUREs:
SomethingInside [label] -- will test whether entity [label]
something inside it. [label] can be a number for a ROOM, a NOUN or
a CREATURE.
ShowContents [label] -- will display the contents of the entity
[label] if that entity has something inside it. If there is
nothing inside the entity [label], this token will have no effect.
As an example of how these tokens might be used, let's continue with the
above scenario. Specifically, let's develop some meta-commands for the
situation where the player wishes to SEARCH THE MIDDLE DRAWER:
COMMAND SEARCH THE DRAWER
Present [Middle drawer]
NOUNIsNumber [Middle drawer] ; was specified in input
IsLocked [Middle drawer] ; is locked
PrintMessage [The $adjective$ $noun$ is locked.]
DoneWithTurn
END_COMMAND
COMMAND SEARCH THE DRAWER
Present [Middle drawer]
NOUNIsNumber [Middle drawer] ; was specified in input
IsUnLocked [Middle drawer] ; is unlocked
OpenIt [Middle drawer] ; Open the middle drawer -- first
NOT SomethingInside [Middle drawer] ; it's empty
PrintMessage [The $adjective$ $noun$ is empty.]
DoneWithTurn
END_COMMAND
96
COMMAND SEARCH THE DRAWER
Present [Middle drawer]
NOUNIsNumber [Middle drawer] ; was specified in input
IsUnLocked [Middle drawer] ; is unlocked
OpenIt [Middle drawer] ; Open the middle drawer -- first
SomethingInside [Middle drawer] ; it's NOT empty
PrintMessage [The $adjective$ $noun$ contains:]
ShowContents [Middle drawer] ; Display contents of middle drawer
DoneWithTurn
END_COMMAND
OPENING AND CLOSING PASSAGEWAYS BETWEEN ROOMS
The ChangePassageway token can be used in a meta-command to open or
close passageways between rooms during the game. For example, to open a
secret passage between room [Dungeon cell] and room [Harem] when the
command SESAME is given could be done with the following:
COMMAND SESAME
AtLocation [Dungeon cell]
InRoom [stone wall]
ChangePassageway [South] [Harem] ; open passage South
SwapLocations [stone wall] [wall with opening]
SwapLocations [Harem stone wall] [Harem wall with opening]
; Swap for solid wall with wall with door in Harem also
PrintMessage [A large doorway magically appears]
DoneWithTurn
END_COMMAND
Once this meta-command has opened the passageway between these rooms,
the player could go to room [Harem] from room [Dungeon Cell] by giving
the SOUTH, or conversely go to room [Dungeon Cell] from room [Harem] by
giving the command NORTH. The passageway is opened in both rooms in
opposite directions.
The same token can be used to close a passageway as well. For example,
if the statue in the treasure room was "booby-trapped", a command of GET
STATUE might cause an avalanche of rocks to close the west exit from the
treasure room as follows:
COMMAND GET STATUE
AtLocation [Treasure room]
InRoom [statue]
FlagOFF [Booby trap]
TurnFlagON [Bobby trap]
ChangePassageway [West] [close] ; close passageway to the West
SwapLocations [open doorway] [jumble of rocks]
SwapLocations [other open doorway] [other jumble of rocks]
; Put jumble of rocks in other room also
PrintMessage [Crash and rocks buries the doorway!!]
GetIt [statue] ; You wanted it -- You got it!!
97
DoneWithTurn
END_COMMAND
The #DEFINEs needed for the numbers corresponding to the various
directions are as follows:
#COMMENT macros for the directions used with ChangePassageway
#DEFINE [close] 0
#DEFINE [North] 1
#DEFINE [South] 2
#DEFINE [East] 3
#DEFINE [West] 4
#DEFINE [NorthEast] 5
#DEFINE [NorthWest] 6
#DEFINE [SouthEast] 7
#DEFINE [SouthWest] 8
#DEFINE [Up] 9
#DEFINE [Down] 10
#DEFINE [Enter] 11
#DEFINE [Exit] 12
META-COMMAND REDIRECTION
Meta-commands can be redirected to other meta-commands. The principal
use of this capability is when there are several player input commands
which should be handled by the game in the same way. For example, in
the CAVE adventure, we want the same series of meta-commands to be used
if the player enters "WATER THE PLANT" or "POUR WATER ON THE PLANT".
With meta-command redirection, the series of meta-commands we wish to
use needs to be given only once in the .AGT file. The second use can be
simply redirected to the first. For example, let's assume that all of
the necessary meta-commands are given completely for POUR WATER ON
PLANT, then the appropriate redirection for WATER PLANT could be
accomplished by the following lines in the .AGT file:
COMMAND WATER PLANT
ReDirectTo POUR WATER ON PLANT
END_COMMAND
Notice in the above example that we redirected the meta-command for a
fixed input command (WATER PLANT) to another fixed command (POUR WATER
ON PLANT). It is also possible to redirect meta-commands for ANY words.
For example, if we wished to redirect the meta-command WATER ANY we
could do it with the following:
COMMAND WATER ANY
ReDirectTo POUR WATER ON $NOUN$
END_COMMAND
Notice that by using $NOUN$ in the "redirected" command, we can "map"
the original command's noun (from WATER PLANT or WATER TREE, or WATER
98
whatever) to the new command's object. This redirected command causes
the game to convert a command to "WATER THING" to act as if the player
had actually typed in "POUR WATER ON THING". In addition to $NOUN$, it
is also possible to use $VERB$, $NAME$ and $OBJECT$ whenever we wish to
"map" these words into another use within a redirected command. You
should not use ANY in the redirected command, i.e., ReDirectTo POUR
WATER ON ANY would make AGT think the player had actually typed in "POUR
WATER ON ANY".
META-COMMAND SUBROUTINES
The Master's Edition allows the game designer to create and use
Subroutines within his/her meta-commands. This is done by specifying
the Subroutines in a list in your game source file as follow:
SUBROUTINES
[Sub example 1]
[Sub example 2]
[Subroutine for Random Beep]
...
[Subroutine for something else]
END_SUBROUTINE
There may be up to 15 Subroutines in your list. If you try to define
more than 15 Subroutines, you will get an error message when you compile
your game.
The Subroutines are just like other meta-commands; you may use any
conditional tokens and/or any action tokens you desire. You define your
Subroutines by using the SUBROUTINE# as the "verb" in a normal COMMAND
-- as follows:
COMMAND SUBROUTINE[Sub example 1]
PrintMessage "You are in Subroutine number [Sub example 1]."
END_COMMAND
COMMAND SUBROUTINE[Sub example 1]
PrintMessage "You still are in Subroutine number [Sub example 1]."
Return
END_COMMAND
COMMAND SUBROUTINE[Sub example 1]
! This part of Subroutine [Sub example 1] will never be executed
! because of the RETURN Token in the above COMMAND
PrintMessage "Still in Subroutine number [Sub example 1] --
really!"
END_COMMAND
COMMAND SUBROUTINE[Sub example 2]
PrintMessage "You are in Subroutine number [Sub example 2]."
END_COMMAND
99
COMMAND SUBROUTINE[Sub example 2]
PrintMessage "You still are in Subroutine number [Sub example 2]."
END_COMMAND
COMMAND SUBROUTINE[Sub example 2]
! The next Token is an example of a "nested" subroutine, i.e.,
! Subroutine [Sub example 2] calls Subroutine [Sub example 1]
DoSubroutine [Sub example 1]
PrintMessage "Still in Subroutine number [Sub example 2] --
really!"
Return
END_COMMAND
IMPORTANT NOTE: There must NOT be a space after the word SUBROUTINE
following the COMMAND or you will get an error indicating that the verb
"SUBROUTINE" is not a valid verb. If you have logic problems with your
subroutines, be sure to check that every subroutine as one or more
RETURNs!
These Subroutines might be called in the body of your game by doing
something like the following:
COMMAND DRINK HANDCUFFS <-- Dumb command, just an example!
...
DoSubroutine [Sub example 1]
PrintMessage "Back in DRINK HANDCUFFS meta-command!"
...
DoneWithTurn
END_COMMAND
COMMAND EAT HANDCUFFS <-- Dumb command, just an example!
...
DoSubroutine [Sub example 2]
PrintMessage "Back in EAT HANDCUFFS meta-command!"
...
DoneWithTurn
END_COMMAND
If the player gave the input command DRINK HANDCUFFS, he/she would see
the following on the screen:
You are in Subroutine number 1.
You still are in Subroutine number 1.
Back in DRINK HANDCUFFS meta-command!
If the player gave the input command EAT HANDCUFFS, he/she would see the
following on the screen:
100
You are in Subroutine number 2.
You still are in Subroutine number 2.
You are in Subroutine number 1.
You still are in Subroutine number 1.
Still in Subroutine number 2 -- really!
Back in EAT HANDCUFFS meta-command!
Here is a little more meaningful example from the HURRY game. First, we
define three subroutines as follows:
SUBROUTINES
[Player Dies! Subroutine]
[Player Wins! Subroutine]
[Player Loses! Subroutine]
[Game Ends! Subroutine]
END_SUBROUTINES
COMMAND SUBROUTINE[Player Dies! Subroutine]
StopSong
PlaySong [Funeral Dirge]
BlankLine
PrintMessage "Sorry, but you have died."
Return
END_COMMAND
COMMAND SUBROUTINE[Player Wins! Subroutine]
StopSong
PlaySong [Winner's Fan Fare]
BlankLine
PrintMessage "Congratulations! You have won the game."
Return
END_COMMAND
COMMAND SUBROUTINE[Player Loses! Subroutine]
StopSong
PlaySong [Circus Music]
BlankLine
PrintMessage
Sorry, Buzz, but you blew it! You have just lost the game.
END_Message
Return
END_COMMAND
COMMAND SUBROUTINE[Game Ends! Subroutine]
BlankLine
PrintMessage "The game is now over and the final score is ...."
BlankLine
ShowScore
BlankLine
WaitForReturn
ShowPicture [THE-END pic]
EndGame
101
Return
END_COMMAND
Now let's show a couple of the ways that these subroutines are used in
the HURRY game. Specifically, the player will die and the game will end
when the player does something extremely dangerous or stupid, such as
(1) staying too long in the tiger's cage without any meat to feed it,
(2) wearing the gorilla suit in the cage with a real gorilla, or (3)
jumping to the ground when hanging on the high-wire. These three
situations are handled in the HURRY game via the following three
meta-commands:
COMMAND ANY
Present [Straw]
NOT InRoom [Meat]
Chance 25
PrintMessage
The tiger suddenly decides to have dinner and you are it!
END_Message
DoSubRoutine [Player Dies! Subroutine]
DoSubRoutine [Game Ends! Subroutine]
DoneWithTurn
END_COMMAND
COMMAND ANY
Present [Straw - Gorilla]
IsWearing [Gorilla Suit]
Chance 50
PrintMessage
The gorilla suddenly figures out that you are a rival gorilla
(because of your gorilla suit) and decides that it does not want
any rivals. It rushes you and grabs you with both of its huge
hands. The gorilla lifts you up above its head, shakes you in the
air, and then throws you to the floor of the cage with a thunk! It
then jumps up and down on your body until you finally die.
END_Message
DoSubRoutine [Player Dies! Subroutine]
DoSubRoutine [Game Ends! Subroutine]
DoneWithTurn
END_COMMAND
COMMAND JUMP
AtLocation [Hanging On Wire]
PrintMessage [You let go of the wire and fall down...]
DoSubRoutine [Player Dies! Subroutine]
DoSubRoutine [Game Ends! Subroutine]
DoneWithTurn
END_COMMAND
Below is a meta-command that causes the player to lose the game (but not
die) when the villain of the game, the evil clown Boffo, escapes before
the player can capture him:
102
COMMAND ANY
Present [Boffo in Balloon overhead]
VerbIsDirection
PrintMessage "Boffo's balloon disappears over the horizon."
Destroy [Boffo in Balloon overhead]
TurnFlagOFF [Doing "End Game"]
DoSubRoutine [Player Loses! Subroutine]
DoSubRoutine [Game Ends! Subroutine]
END_COMMAND
Finally, below is a meta-command that causes the player to win the game
when he captures the evil Boffo by slapping the handcuffs on him:
COMMAND PUT CUFFS ON BOFFO
Present [Handcuffs]
Present [Sad Boffo]
AtLocation [Field K]
OR
AtLocation [On Rocks]
OR
AtLocation [Tree Top K]
PrintMessage
As you slap the cuffs on Boffo, you can taste the sweet fruits of
victory!
END_Message
PlusScore 70
DoSubRoutine [Player Wins! Subroutine]
DoSubRoutine [Game Ends! Subroutine]
DoneWithTurn
END_COMMAND
Subroutines may be "nested" to any level (only limited by available
memory of the player's computer). You should exercise great care when
"nesting" subroutines, however. It is possible to create "endless
loops" if you are not very careful. If you seem to be having trouble
following the logic and flow of your Subroutines (or other
meta-commands) be sure to use the "debug" option by giving the command
AGTDEBUG.
Whenever you have logic problems with your subroutines, be sure to check
that every subroutine as one or more RETURNs.
As you can see from the above examples there are two new tokens used
with Subroutines:
DoSubroutine {num1} -- This causes the meta-commands in
Subroutine num1 to be executed
Return -- This causes an immediate exit from
the currently executing Subroutine
(if any), i.e., normal command
processing would resume immediately
103
after the DoSubroutine token that
called the Subroutine in the first
place. Each Subroutine must have at
least one "Return"!
ORGANIZATION OF META-COMMANDS IN THE .AGT FILE
Meta-commands like those described above are processed sequentially by
their order of appearance in the .AGT file. As a result, the COMMANDs
order is very important!! For example, let's consider a series of
meta-commands to define a new verb FILL. We want to be able to fill a
bottle with water or oil depending upon where we are. We want to break
a vase, whenever we try to fill the vase. Finally, we want to print
several default messages, such as "The bottle is already full.", or
"The $noun$ isn't here, so you can't $verb$ it!", or "There is nothing
here to put in the $noun$." or "You have to be kidding! You can't
$verb$ a $noun$!!" This can be done with the following seven
meta-commands for the verb FILL:
FLAG [bottle is already full]
(1) COMMAND FILL ANY
NOT NOUNPresent
PrintMessage [The $noun$ isn't here, so you can't $verb$ it!]
DoneWithTurn
END_COMMAND
(2) COMMAND FILL BOTTLE
FlagON [bottle is already full]
PrintMessage [The bottle is already full.]
DoneWithTurn
END_COMMAND
(3) COMMAND FILL BOTTLE
AtLocation [inside building]
OR
AtLocation [valley by stream]
OR
AtLocation [bottom of pit with stream]
OR
AtLocation [cavern with waterfall]
OR
AtLocation [reservoir]
OR
AtLocation [by building]
PrintMessage [The bottle is now full of water.]
SwapLocations [empty bottle] [water-filled bottle]
TurnFlagON [bottle is now full]
DoneWithTurn
END_COMMAND
104
(4) COMMAND FILL BOTTLE
AtLocation [east pit of two-pit room]
PrintMessage [The bottle is now full of oil.]
SwapLocations [empty bottle] [oil-filled bottle]
TurnFlagON [bottle is now full]
DoneWithTurn
END_COMMAND
(5) COMMAND FILL BOTTLE
PrintMessage [There is nothing here to put in the $noun$.]
DoneWithTurn
END_COMMAND
(6) COMMAND FILL VASE
Destroy [Ming vase]
PutInCurrentRoom [broken vase pottery shards]
PrintMessage [You clumsy oaf! You broke the vase.]
DoneWithTurn
END_COMMAND
(7) COMMAND FILL ANY
PrintMessage [You must be kidding! You can't $verb$ a $noun$!]
DoneWithTurn
END_COMMAND
The numbers shown in front of each of the COMMANDs are just for ease of
this discussion. Numbers like these should NEVER actually be included
in a .AGT file, because they would lead to serious bugs!
If these COMMANDs were in the .AGT file in the order shown, when the
player entered a command to "FILL something", AGT would first try
COMMAND (1) which would test whether the "something" was present. If it
was not present, COMMAND (1) would print the default message "The
something isn't here, so you can't fill it!" and the DoneWithTurn would
cause all AGT process to cease for this turn. Only if the something was
present, would AGT try COMMANDS (2), (3), etc.
COMMAND (2) to (5) will only be tried in the "something" was the BOTTLE.
COMMAND (2) would be tried first, and it would test if the bottle was
already full and give an appropriate message if it was full. COMMAND
(3), which would only be tried if the bottle was empty, would test if
the player was located in places where it was possible to get water, and
fills the bottle with water if possible. COMMAND (4), which would only
be tried if there was no water at the current location, would test if
the player was at location 24, where there is oil, and fill the bottle
with oil, if possible. COMMAND (5) would only be tired if the player
was not located near a source of water or a source of oil and it would
print a message that "There is nothing here to put in the bottle".
COMMAND (6) only works if the player's input is FILL VASE. Because AGT
got past COMMAND (1), we know that the vase is present (otherwise
COMMAND (1) would have caused an "error" message to be printed).
105
COMMAND (6) causes the broken pottery shards to be switched with the
vase and an appropriate message to be printed.
COMMAND (7) is the "default" condition for the verb FILL. It is
activated only if the player gave the input "FILL something" and the
"something" is present, but it is not the BOTTLE or the VASE. For
example, if the player entered FILL THE ROCK, COMMAND (7) would cause
"You must be kidding! You can't fill a rock!" to be printed.
The order of these COMMANDs is very important! Specifically, COMMAND
(1) must be first and COMMAND (7) must be last in order for AGT to give
the "correct" and logical default responses to the verb FILL. Further,
COMMAND (2) must precede and COMMAND (5) must follow COMMANDs (3) and
(4) in order for the input "FILL BOTTLE" to work logically. It is
important to understand why the above sequence is critical. Study the
sequence again, if necessary.
Besides, the order of COMMANDs for a specific verb (like FILL), it is
also important to arrange the verbs within the .AGT file in a reasonable
manner. Specifically, all the meta-commands for each verb should be
grouped together in the .AGT file. For example:
; ANY Commands
(1) COMMAND ANY
.
.
(37) COMMAND ANY
; READ Commands
(38) COMMAND READ BOOK
.
.
(46) COMMAND READ ANY
; SEARCH Commands
(47) COMMAND SEARCH CLOSET
.
.
(54) COMMAND SEARCH ANY
; CLIMB Commands
(55) COMMAND CLIMB ROPE
.
.
(69) COMMAND CLIMB ANY
; SQUEEZE Commands
106
(70) COMMAND SQUEEZE LEMON
.
.
(82) COMMAND SQUEEZE ANY
.
.
; AFTER Commands
(91) COMMAND AFTER
.
.
(112) COMMAND AFTER
; SUBROUTINE Commands
(131) COMMAND SUBROUTINE1
.
.
(142) COMMAND SUBROUTINE2
.
.
(146) COMMAND SUBROUTINE3
.
.
All the ANY meta-commands are grouped together; all the READ meta-comma-
nds are together, etc. All the AFTER meta-commands are grouped
together; all the SUBROUTINE meta-commands are together. Not only is
this easier to follow and debug, but it is faster for AGT to process.
This is because, AGT processes these meta-commands using a variation of
a technique called "Indexed Sequential Access Method" (also called
ISAM). What this means is: AGT keeps track of the first and last
meta-commands for each verb. For example, if the verb was CLIMB, AGT
would only consider meta-commands with indices from 55 to 69. But
within this group, AGT considers them sequentially.
107
PART 4: SAMPLE AGT META-COMMAND SCENARIOS
This Part of the manual presents a number of scenarios where meta-
language commands have been used to create typical game situations.
These scenarios are presented in detail by showing how ROOMs, NOUNs and
CREATUREs data are used in the .AGT file, how messages are put in the
.AGT file, and finally how the meta-commands are written to accomplish
the desired effects in the .AGT file. The specific scenarios to be
presented include: (1) defining the actions for the new verb FIND, (2)
random activities by a castle guard, and (3) interacting with other
characters.
SCENARIO 1: "FIND" VERB ACTIONS
One final scenario from the COLOSSAL CAVE adventure. In this scenario,
we want to define several actions/responses to the player's input using
the custom user-defined verb "FIND". Pay particular attention to how
the player is offered a hint (for 5 points) if he inputs "FIND CAVE".
In the CAVE.AGT file we would define a custom verb as:
VERB
Dummy_Verb1 FIND
END_VERB
Several messages are needed in the CAVE.AGT file as follows:
MESSAGE [You are already carrying the $noun$, dummy!]
You are already carrying the $noun$, dummy!
END_MESSAGE
MESSAGE [I would try the stream.]
I don't know where the cave is, but hereabouts no stream can run on
the surface for very long. I would try the stream.
END_MESSAGE
MESSAGE [I cannot tell you where remote things are.]
I can only tell you what you see as you move about and manipulate
things. I cannot tell you where remote things are.
END_MESSAGE
MESSAGE [Okay, If you're so smart, do it yourself!]
Okay, If you're so smart, do it yourself!
END_MESSAGE
MESSAGE [I believe it is right here with you.]
I believe what you want is right here with you.
END_MESSAGE
108
MESSAGE [The Dwarf's knife vanished]
The Dwarf's knife vanished as it struck the wall of the cave.
END_MESSAGE
MESSAGE [It must be around here somewhere.]
I daresay whatever you want is around here somewhere.
END_MESSAGE
MESSAGE [The hint will cost you 5 points.]
The hint will cost you 5 points.
END_MESSAGE
MESSAGE [Do you want the hint?]
Do you want the hint?
END_MESSAGE
The meta-commands for FIND in the CAVE.AGT file would be as follows: (Be
sure and understand the importance of the order of these COMMANDs.)
FLAG [cave is closed]
FLAG [temp flag]
FLAG [Dwarf is here]
FLAG [Hint about cave has been offered]
; FIND meta-commands
COMMAND FIND KNIFE
PrintMessage [The Dwarf's knife vanished] ; as it hits wall
DoneWithTurn
END_COMMAND
COMMAND FIND ANY
NOUNIsCarrying
PrintMessage [You are already carrying the $noun$, dummy!]
DoneWithTurn
END_COMMAND
COMMAND FIND ANY
FlagON [Cave is closed]
OR
NOUNPresent ; NOUN is here already
PrintMessage [It must be around here somewhere.]
DoneWithTurn
END_COMMAND
COMMAND FIND DWARF
FlagON [Dwarf is here]
PrintMessage [I believe it is right here with you.]
DoneWithTurn
END_COMMAND
109
COMMAND FIND CAVE
FlagOFF [Hint about cave has been offered]
TurnFlagON [Hint about cave has been offered]
PrintMessage [Do you want the hint?]
PromptForYes
TurnFlagON [temp flag] ; hint has been rejected - so far
PrintMessage [The hint will cost you 5 points.]
PrintMessage 1 ;Is that OK?
PromptForYes
TurnFlagOFF [temp flag] ; Offer of hint has been accepted
PrintMessage [I would try the stream.] ; Follow the stream
MinusScore 5 ;hint costs 5 points
DoneWithTurn
END_COMMAND
COMMAND FIND CAVE
FlagON [temp flag] ; Offer of hint was rejected
TurnFlagOFF [temp flag] ; Turn temporary Flag OFF now
PrintMessage [Okay, If you're so smart, do it yourself!]
DoneWithTurn
END_COMMAND
COMMAND FIND ANY
PrintMessage [I cannot tell you where remote things are.]
; Default message for FIND
DoneWithTurn
END_COMMAND
SCENARIO 2: RANDOM ACTIVITIES BY GUARD
This is a modification of a scenario from CRUSADE adventure. In this
scenario we want to create a number of encounters with guards in various
rooms of the Baron's castle. We will use only one CREATURE (the Guard)
and move him around from room to room randomly. The player can fight
the guard, and will be thrown into a dungeon cell if he loses, and will
cause the guard to be replaced with an unconscious guard if he wins.
The player can wear a disguise by wearing the Baron's armor. If the
guard encounters the player wearing the armor, the guard will mistake
the player for the Baron and leave the room. If the player attempts to
talk to the guard without giving the proper password, the guard will
capture the player and throw him into the dungeon. If the player angers
the guard in Room [small room high up in cavern wall], the guard will
throw the player down to the cavern floor far below where the player
will lose consciousness and later awake with a broken leg. The leg will
take a random number of turns to heal. Before it heals, the player will
be unable to move around.
To give as complete a picture as possible, the needed data for this
scenario will be shown from all its "glory." First, we will define the
CREATURE, ROOMs and the various NOUNs needed as:
110
CREATURE [Baron's guard]
guard
Baron's
You see one of the Baron's guards. He looks very angry.
LOCATION [small room high up in cavern wall]
HOSTILE
MAN
END_CREATURE
CREATURE_DESCR [Baron's guard]
The guard is about 6 foot 8 inches tall, but he appears even bigger
as he looms over you. He looks mean and is rather ugly.
END_CREATURE_DESCR
ROOM [Large cavern]
Large cavern
EAST [small stone room]
LIGHT [Blazing torch]
END_ROOM
ROOM_DESCR [Large cavern]
You are in a very large cavern with high sheer walls. A passage
leads off to the east.
END_ROOM_DESCR
NOUN [cavern walls]
walls
cavern
The cavern walls are quite steep. You can't see any way to climb
them.
LOCATION [Large cavern]
UNMOVABLE
NOUN_SYNONYMS WALL
PLURAL
END_NOUN
NOUN_DESCR [cavern walls]
The walls are very steep and quite smooth. You can't see any hand
or foot holds.
END_NOUN_DESCR
NOUN [small opening]
opening
small
There is an opening in the wall -- high up near the roof of the
cavern.
LOCATION [Large cavern]
UNMOVABLE
END_NOUN
111
NOUN_DESCR [small opening]
You see a dim light shining out of the opening, but it is too high
and far to see more. It looks impossible to get up to the opening
from your location at the bottom of the cavern.
END_NOUN_DESCR
ROOM [small room high up in cavern wall]
Small room
SOUTH [stone passage]
LIGHT [Blazing torch]
END_ROOM
ROOM_DESCR [small room high up in cavern wall]
You are in a small room carved into the sheer cavern wall. The
south part of the room is totally open and looks out on to the
cavern floor far below. Be careful not to go south! There is a
doorway to the north.
END_ROOM_DESCR
NOUN [broken leg]
leg
broken
You have a broken leg and are unable to move.
LOCATION [Nowhere]
UNMOVABLE
END_NOUN
NOUN_DESCR [broken leg]
Your leg hurts like the dickens! You are quite discouraged because
you will need two good legs to rescue the princess and solve this
adventure!
END_NOUN_DESCR
NOUN [silver armor]
armor
silver
The Baron's silver suit of armor stands nearby.
LOCATION 24
WEIGHT 25
SIZE 25
WEARABLE
POINTS 10
END_NOUN
NOUN_DESCR [silver armor]
The armor is quite fancy, but it still looks like it would be
useful in a fight. It would cover its occupant from head to foot.
END_NOUN_DESCR
112
NOUN [unconscious guard]
guard
unconscious
An unconscious guard lies at your feet.
LOCATION 0
WEIGHT 200
END_NOUN
NOUN_DESCR [unconscious guard]
The guard's unconscious body lies in a heap at your feet. You have
to step over him as you move about the passageway. He looks like
he will be out of action for a long time.
END_NOUN_DESCR
ROOM [Guard's Quarters]
Guard's quarters
EAST [Portico]
END_ROOM
ROOM_DESCR [Guard's Quarters]
You are in the guard's quarters. It looks like a pig sty -- it is
so messy. The door is to the east.
END_ROOM_DESCR
HELP [Guard's Quarters]
Leave quickly. It is very dangerous to linger here!
END_HELP
ROOM [Dungeon Cell]
Cell
[No obvious exits]
END_ROOM
ROOM_DESCR [Dungeon Cell]
You are in a dingy dungeon cell. There is straw on the floor. The
cell is cold and damp. You are very depressed by just being here.
END_ROOM_DESCR
In addition, we must define these needed messages:
MESSAGE [The guard looks at you suspiciously]
The guard looks at you suspiciously because you neglected to
identify yourself by using the proper password. He knows you
shouldn't be here and decides that he should take you to the Baron
for questioning. He rushes toward you.
END_MESSAGE
113
MESSAGE [Sorry, but you can't]
What a great idea! You must have played this game before, but
unfortunately you can't do that now. It is still a good idea and
you may wish to try it some other time. But now it is impossible
END_MESSAGE
MESSAGE [The guard simply won't let you]
because the guard simply won't let you $verb$ the $noun$.
END_MESSAGE
MESSAGE [An angry-looking guard suddenly enters]
An angry-looking guard suddenly enters the room. He eyes you
suspiciously and begins to move quickly and carefully toward you.
He reaches for his sword, but pauses as if he is waiting for you to
make the first move.
END_MESSAGE
MESSAGE [Guard throws you over the edge]
The guard gets mad at you because he knows you aren't allowed here.
He picks you up and throws you over the edge to the cavern floor
far below. He stands at the edge looking down at you and
laughingly cries, "Stay out! If you know what is good for you.
Next time, I will get rough!" He laughs again and that is the
last thing you remember as you drift off into unconsciousness.
When you awake, you find...
END_MESSAGE
MESSAGE [with a broken leg.]
with a broken leg.
END_MESSAGE
MESSAGE [Your leg has finally healed.]
Your leg has finally healed. You are now free to resume your
quest.
END_MESSAGE
MESSAGE [Guard thinks you are the Baron and leaves]
The guard looks you over very carefully, but because you are
wearing the Baron's armor, the guard mistakes you for the Baron.
"Sorry to disturb you, my Lord!", he says as he quickly leaves the
room.
END_MESSAGE
MESSAGE [It was a fierce fight]
The guard grabs your throat with his big hands. He squeezes until
you can barely breathe. You struggle and try to pull his hands
away.
END_MESSAGE
114
MESSAGE [but you lost.]
Finally, you slip into unconsciousness. When you awake you find
yourself in a strange and ugly little room.
END_MESSAGE
MESSAGE [but you won!]
At last, you pry his fingers off your wind pipe. Now able to
breathe, you get enough strength to slam your elbow into his gut.
He lets go of you and doubles over. You kick him in a very
vulnerable part of his anatomy and he crumples in a pile on the
floor.
END_MESSAGE
Now, here are the various meta-commands:
COMMAND ANY
NOT InRoom [Baron's guard]
NOT InRoom [unconscious guard]
Destroy [Baron's guard] ; disappears after player leaves room
Destroy [unconscious guard]
END_COMMAND
COMMAND ANY
Chance 5 [5 % chance of guard appearing]
AtLocationGT [Large cavern]
NOT InRoom [Baron's guard]
NOT InRoom [unconscious guard]
PutInCurrentRoom [Baron's guard]
PrintMessage [An angry-looking guard suddenly enters]
BlankLine
END_COMMAND
COMMAND ANY
Chance 50 ; 50 % chance of guard appearing in his own quarters
AtLocation [Guard's Quarters]
NOT InRoom [Baron's guard]
NOT InRoom [unconscious guard]
PutInCurrentRoom [Baron's guard]
PrintMessage [An angry-looking guard suddenly enters]
BlankLine
END_COMMAND
COMMAND ANY
InRoom [Baron's guard]
IsWearing [silver armor]
PrintMessage [Guard thinks you are the Baron and leaves]
Destroy [Baron's guard] ; Guard disappears
END_COMMAND
115
COMMAND ANY
Chance 25
AtLocation [small room high up in cavern wall]
InRoom [Baron's guard]
GetIt [broken leg] ; give broken leg to player
GoToRoom [Large cavern] ; guard throws you down
PrintMessage [Guard throws you over the edge]
DoneWithTurn ; no further action -- get next input
END_COMMAND
Now the meta-commands dealing with the broken leg:
COMMAND ANY
IsCarrying [broken leg]
VerbIsDirection [Trying to move]
PrintMessage [Sorry, but you can't]
PrintMessage [with a broken leg.]
DoneWithTurn ; no further action -- get next input
END_COMMAND
COMMAND ANY
Chance 20
IsCarrying [broken leg]
PrintMessage [Your leg has finally healed.]
BlankLine
Destroy [broken leg] ; get rid of broken leg
END_COMMAND
Now the meta-commands corresponding to specific input from the player:
COMMAND GET ANY
InRoom [Baron's guard]
PrintMessage [Sorry, but you can't]
PrintMessage [The guard simply won't let you]
DoneWithTurn ; no further action -- get next input
END_COMMAND
COMMAND GET ANY
IsCarrying [broken leg]
PrintMessage [Sorry, but you can't]
PrintMessage [with a broken leg.]
DoneWithTurn ; no further action -- get next input
END_COMMAND
COMMAND OPEN ANY
InRoom [Baron's guard]
PrintMessage [Sorry, but you can't]
PrintMessage [The guard simply won't let you]
DoneWithTurn ; no further action -- get next input
END_COMMAND
116
COMMAND ATTACK GUARD
InRoom [Baron's guard]
PrintMessage [It was a fierce fight]
TurnFlagON [temp flag] ; Set Temporary Flag to ON
Chance 25 [25 % chance of winning fight]
PrintMessage [but you won!]
TurnFlagOFF [temp flag] ; Turn Temporary Flag OFF now
SwapLocations [unconscious guard] [Baron's guard]
DoneWithTurn ; no further action -- get next input
END_COMMAND
COMMAND ATTACK GUARD
InRoom [Baron's guard] [angry guard]
FlagON [temp flag] ; was not turned OFF in last COMMAND
TurnFlagOFF [temp flag] ; Turn Flag OFF now
PrintMessage [but you lost.]
SendAllToRoom [Guard's Quarters]
GoToRoom [Dungeon Cell] ; Guard puts you in dungeon cell
SendToRoom [Torch] [Dungeon Cell]
DoneWithTurn ; no further action -- get next input
END_COMMAND
COMMAND TALK TO GUARD
PrintMessage [The guard looks at you suspiciously]
PrintMessage [It was a fierce fight]
PrintMessage [but you lost.]
SendAllToRoom [Guard's Quarters]
GoToRoom [Dungeon Cell] ; Guard puts you in dungeon cell
SendToRoom [Torch] [Dungeon Cell] ; Put torch in dungeon with you
DoneWithTurn ; no further action -- get next input
END_COMMAND
COMMAND ASK GUARD ABOUT ANY
ReDirectTo TALK TO GUARD
END_COMMAND
SCENARIO 3: INTERACTION WITH OTHER CHARACTERS
Let's develop an example of communicating with other characters in an
adventure game. Specifically, let's consider a situation in a Star Trek
adventure game were we wish to be able to experience the following
interchange between several of the standard Star Trek characters and the
player, who is playing the role of Captain James T. Kirk:
You are on the Bridge, the circular room at the top of the Enterprise's
disk. The walls are decked with crew members seated or standing at their
posts. In the center of the room is your command chair. Along one side
of the room is a large viewscreen. The only exit, via turbolift, is aft.
The viewscreen shows the emptiness and vastness of space.
Spock stands alert but relaxed, with his arms folded behind his back.
Chekov sits behind the weapons control console.
117
Lieutenant Uhura listens intently to her earphones.
At the navigator's station, Sulu sits behind a console of controls.
What now? AFT
You are in the TurboLift, a small closet-like room. The Bridge is to
your west.
Spock stands alert but relaxed, with his arms folded behind his back.
What now? WARP 10
Spock: Jim, surely you realize that you are not on the Enterprise's
Bridge. The command "warp 10" is quite inappropriate here.
What now? WEST
You are on the Bridge, the circular room at the top of the Enterprise's
disk. The walls are decked with crew members seated or standing at their
posts. In the center of the room is your command chair. Along one side
of the room is a large viewscreen. The only exit, via turbolift, is aft.
The viewscreen shows the emptiness and vastness of space.
Spock stands alert but relaxed, with his arms folded behind his back.
Chekov sits behind the weapons control console.
Lieutenant Uhura listens intently to her earphones.
At the navigator's station, Sulu sits behind a console of controls.
What now? SCOTTY, WARP 10
Spock: Captain, should you have Doctor McCoy check your eye sight?
Surely, you can see that Scotty isn't here.
What now? CHEKOV, WARP 10
Spock: Your extensive command experience should have convinced you that
better results can be obtained when the appropriate member of the crew
performs this operation. Permit me to redirection your command to the
proper crew member.
Spock: Sulu, warp 10
Sulu: What course should I plot first, Captain?
What now? PLOT A COURSE FOR QWERTY
Sulu: Plotting a course for the planet Qwerty, Captain.
What now? WARP 16
Spock: Captain, surely you realize that the Enterprise is only capable
of Warp 1 through Warp 12, plus Impulse power, of course.
118
What now? WARP 10
Sulu: Going to warp factor 10.
To see how this scene is achieved, first let's examine the relevant
entries in the .AGT file. There are only two Rooms in the scene, the
Bridge and the TurboLift; their descriptions are as follows:
ROOM [Bridge]
Bridge
EAST [Turbolift: Deck 1]
ENTER [Turbolift: Deck 1]
EXIT [Turbolift: Deck 1]
END_ROOM
ROOM_DESCR [Bridge]
You are on the Bridge, the circular room at the top of the
Enterprise's disk. The walls are decked with crew members seated
or standing at their posts. In the center of the room is your
command chair. Along one side of the room is a large viewscreen.
The only exit, via turbolift, is aft.
END_ROOM_DESCR
ROOM [Turbolift: Deck 1]
Turbolift: Deck 1
WEST [Bridge]
ENTER [Bridge]
EXIT [Bridge]
END_ROOM
ROOM_DESCR [Turbolift: Deck 1]
You are in the TurboLift, a small closet-like room. The Bridge is
to your west.
END_ROOM_DESCR
Next, let's see how the Nouns are described in the .AGT file:
NOUN [ship's course]
course
ship's
You see the course plotted on the navigator's console.
LOCATION [Nowhere]
NOUN_SYNONYMS CONSOLE
END_NOUN
NOUN_DESCR [ship's course]
The navigator's console shows the ship's course plotted in light
blue. The Enterprise (shown as a red circle) is on course.
END_NOUN_DESCR
119
NOUN [Viewscreen]
Viewscreen
Big
The viewscreen shows the emptiness and vastness of space.
LOCATION [Bridge]
UNMOVABLE
NOUN_SYNONYMS SCREEN
END_NOUN
NOUN [Planet Qwerty]
Qwerty
Planet
You notice on the viewscreen: The planet Qwerty below.
LOCATION [Nowhere]
UNMOVABLE
NOUN_SYNONYMS PLANET
END_NOUN
Notice that only the Viewscreen, Noun [Viewscreen], is in the Bridge at
the beginning of the scene. The other Nouns are initially "nowhere",
and will be put in the Bridge, when appropriate. Specifically, The
Ship's Course, Noun [ship's course], will be put in the Bridge as soon
as a command is given to plot a course. Similarly, the Noun [Planet
Qwerty] -- shown in the Viewscreen, will replace the empty Viewscreen
when the Enterprise gets close to the planet and assumes orbit.
There are a number of Creatures in the scene. Their descriptions would
be given in the .AGT file as follows:
CREATURE [Spock]
Spock
Commander
Spock stands alert but relaxed, with his arms folded behind his
back.
LOCATION [Bridge]
GROUPMEMBER [Have Spock automatically follow player]
END_CREATURE
CREATURE_DESCR [Spock]
Spock is the only Vulcan member of your crew. He wears a blue
shirt with a gold Star Fleet insignia.
END_CREATURE_DESCR
CREATURE [Chekov]
Chekov
Lieutenant
Chekov sits behind the weapons control console.
LOCATION [Bridge]
END_CREATURE
120
CREATURE_DESCR [Chekov]
Chekov is sitting at his assigned station pressing keys on the
weapons control Panel and monitoring the screen in front of him.
END_CREATURE_DESCR
CREATURE [Uhura]
Uhura
Lieutenant
Lieutenant Uhura listens intently to her earphones.
LOCATION [Bridge]
UNMOVABLE
END_CREATURE
CREATURE_DESCR [Uhura]
Uhura is sitting in her communications station listening to her
earphones and monitoring all of the known hailing frequencies.
END_CREATURE_DESCR
CREATURE [Sulu]
Sulu
Commander
At the navigator's station, Sulu sits behind a console of controls.
LOCATION [Bridge]
UNMOVABLE
END_CREATURE
CREATURE_DESCR [Sulu]
Sulu is sitting next to Chekov, monitoring the lit navigation
console.
END_CREATURE_DESCR
CREATURE [Scotty]
Scott
Commander
Commander Scott sits at his console, monitoring the ship's engines.
LOCATION 52 [Engine Room]
UNMOVABLE
CREATURE_SYNONYMS SCOTTY
END_CREATURE
CREATURE_DESCR [Scotty]
Scott is the best Engineering Officer in the Federation.
END_CREATURE_DESCR
All of these Creatures are initially in the Bridge except for Commander
Scott, who is in the Engine Room, naturally.
Only one other entry from the .AGT file needs to be specified in order
for the scene to work as show, and that is the definition of verbs:
121
VERB
EAST AFT
Dummy_Verb1 WARP
Dummy_Verb2 PLOT SET CHART
END_VERB
Notice that AFT is defined as a synonym for EAST. WARP is defined as a
"custom" verb so that commands like WARP 9 will be understood by the
parser and the rest of the AGT driver program (MRUN.EXE). Integer
numbers like 9, 12, etc., are always acceptable "Nouns" to the parser;
however, you must use meta-commands to deal with numbers as Nouns
properly. PLOT, SET and CHART are all synonyms so that the player can
enter PLOT A COURSE, or SET A COURSE or CHART A COURSE and they will all
be treated the same by AGT.
The messages needed for the scene are contained in the .AGT file and are
shown below:
MESSAGE [Sorry, but $Name$ doesn't seem to be here.]
Spock: Captain, should you have Doctor McCoy check your eye sight?
Surely, you can see that $Name$ isn't here.
END_MESSAGE
MESSAGE [Spock: You should address appropriate person.]
Spock: Your extensive command experience should have convinced you
that better results can be obtained when the appropriate member of
the crew performs this operation. Permit me to redirection your
command to the proper crew member.
END_MESSAGE
MESSAGE [Spock redirects command to Sulu for you.]
Spock: Sulu, $verb$ $noun$.
END_MESSAGE
MESSAGE [Spock: "$VERB$ $NOUN$" is inappropriate here.]
Spock: Jim, surely you realize that you are not on the Enterprise's
Bridge. The command "$VERB$ $NOUN$" is quite inappropriate here.
END_MESSAGE
MESSAGE [The Enterprise can only travel at warp 1 to 12.]
Spock: Captain, surely you realize that the Enterprise is only
capable of Warp 1 through Warp 12, plus Impulse power, of course.
END_MESSAGE
MESSAGE [Sulu: What course to plot first, Captain?]
Sulu: What course should I plot first, Captain?
END_MESSAGE
MESSAGE [Sulu: Going to warp factor $noun$.]
Sulu: Going to warp factor $noun$.
END_MESSAGE
122
MESSAGE [Sulu: Plotting course for $Object$.]
Sulu: Plotting a course for the planet $Object$, Captain.
END_MESSAGE
Now for the heart of the scene's interaction, the .AGT file meta-
commands. First, any input command that the player addresses to a valid
Creature in the game will first be tried against a group of meta-
commands that are addressed to ANYBODY. This will happen automatically.
For example, consider the following ANYBODY meta-commands:
COMMAND ANYBODY, ANY
NOT NamePresent [Addressee isn't here.]
PrintMessage [Sorry, but $Name$ doesn't seem to be here.]
DoneWithTurn
END_COMMAND
COMMAND ANYBODY, WARP ANY
AtLocation [Bridge]
NOT NameIsNumber [Sulu] ; Command isn't being addressed to Sulu
PrintMessage [Spock: You should address appropriate person.]
PrintMessage [Spock redirects command to Sulu for you.]
RedirectTo WARP $NOUN$
END_COMMAND
COMMAND ANYBODY, WARP ANY
RedirectTo WARP $NOUN$
END_COMMAND
The first of the above will be tried for any player command that has
been addressed to a Creature, no matter what the command is. For
example, this command will be tried if the player enters SPOCK, FOLLOW
ME or SULU, WARP 12. However, it would not be tried if the player did
not direct his command to anyone, i.e., it would not be tried if the
player simply inputs WARP 12 without addressing it to a specific
creature. This first meta-command simply tests that the Creature being
addressed in the command is at the current location and prints a "error"
message if the creature isn't there.
The second and third meta-commands above are tried whenever a player
addresses his command to a Creature (any Creature, however) and the
command is to WARP something. The second meta-command checks if the
creature being addressed is Sulu, and if it isn't -- gives an "error"
message and redirects the command to Sulu. The third meta-command would
only be tried if the player input SULU, WARP Something. This meta-
command simply redirects the command to WARP Something, as if the
command had not been addressed to anyone specifically.
These WARP Something meta-commands would be defined in the .AGT file as
follows:
FLAG [Course plotted]
VARIABLE [Warp Number]
123
COMMAND WARP ANY
NOT AtLocation [Bridge]
PrintMessage [Spock: "$VERB$ $NOUN$" is inappropriate here.]
DoneWithTurn
END_COMMAND
COMMAND WARP ANY
NounToVariable [Warp Number] ; Convert Noun to [Warp Number]
VariableGT [Warp Number] 12
OR
VariableLT [Warp Number] 1
PrintMessage [The Enterprise can only travel at warp 1 to 12.]
DoneWithTurn
END_COMMAND
COMMAND WARP ANY
FlagOFF [Course plotted] ; Course has not been plotted yet
PrintMessage [Sulu: What course to plot first, Captain?]
DoneWithTurn
END_COMMAND
COMMAND WARP ANY
FlagON [Course plotted] ; Course has been plotted already
PrintMessage [Sulu: Going to warp factor $noun$.]
DoneWithTurn
END_COMMAND
The first three of the above meta-commands check for various "error"
conditions and give "error" messages if appropriate. Specifically, the
first meta-command tests if the player is not on the Bridge; the second
tests if the warp speed is outside the acceptable range; and the third
tests that a course has already been plotted. Only if none of these
"error" conditions are met, would the fourth meta-command tell that
player that the Enterprise was going to the indicated warp speed.
There are only two more meta-commands required in order for the scene to
work as shown at the start of this section. These meta-commands are
both for the situation where the player enters a command to PLOT A
COURSE TO Somewhere:
COMMAND PLOT COURSE FOR ANY
NOT AtLocation [Bridge]
PrintMessage [Spock: "$VERB$ $NOUN$" is inappropriate here.]
DoneWithTurn
END_COMMAND
COMMAND PLOT COURSE FOR ANY
TurnFlagON [Course plotted] ; Course has now been plotted
DropIt [ship's course] ; Put plotted course on Navigator's console
PrintMessage [Sulu: Plotting course for $Object$.]
DoneWithTurn
END_COMMAND
124
PART 5: "DEBUGGING" YOUR ADVENTURE
Once the "first draft" of your adventure is completed, you will want to
begin a process known as "play testing" or "debugging." This process is
where you (and perhaps a few friends) test your game to see that it
behaves the way you intended -- not the way you actually programmed it.
This process is both very rewarding and very frustrating. You can be
guaranteed that you will discover "bugs" in your game. You can also be
guaranteed that while debugging your game, you will come up with a whole
host of improvements -- your descriptions will become brighter, your
puzzles will become cleverer, and you will think of entirely new and
absolutely brilliant game scenes to "spice" up the game.
The Master's Edition of AGT's MRUN program has a built-in "magic" word
that can make debugging much easier. This magic word is AGTDEBUG
(clever -- don't you think?) When you give the command AGTDEBUG, you
will be given a menu of options that include:
1. MOVING THE PLAYER by being transported instantly to another
room.
2. TOGGLING META-COMMANDS debugging ON and OFF, i.e., it toggles
FLAG 0.
3. GETTING A NOUN -- which enables you to immediately get a
particular noun -- no matter where it is located.
4. MOVING A NOUN -- which enables you to move a noun from its
current location to any other location in the game.
5. MOVING A CREATURE -- which enables you to relocate a creature
from its current location to any other location in the game.
6. LISTING THE ROOMS -- which gives you a complete list of the
numbers and short descriptions for all of the rooms in the
game. This is particularly helpful, when you know you want to
be in the "Dank Dungeon", but you can't remember its room
number.
7. LISTING THE NOUNS -- which gives you a complete list of the
numbers, names and current locations for all of the nouns in
the game. This is particularly helpful, when you know you want
to find the "Iron Maiden", but you can't remember where you
left it.
8. LISTING THE CREATURES -- which gives you a complete list of
the numbers, names and current locations for all of the
creatures in the game. This is particularly helpful, when you
know you want to see if the magic word "QWERTY" really does
make the Ogre run away and hide, but you can't remember where
125
the Ogre is to begin with.
Remember, you can use the SCRIPT command to get a hard-copy of any of
these lists.
IMPORTANT NOTE: When you create the final version of your game that you
release to the public, you will want to turn the AGTDEBUG option off.
You can do this by putting the word NO_DEBUG (on a separate line)
somewhere in your final game source file and use MCOMPILE to create a
version of the compiled data files that can not be debugged.
126
PART 6: OPTIONAL GRAPHIC ILLUSTRATIONS
The Master's Edition has the option of having a graphic illustration (or
animated picture) for each ROOM, NOUN, CREATURE and "special event" -
such as a title, or winning the game. These illustrations/animations
can be seen by using the command VIEW (i.e., VIEW TREE, VIEW WIZARD,
etc.) or by using the new picture-related meta-commands. The
illustration or animation will be displayed until a key is pressed and
then the display will return to the normal AGT text-based screen --
ready for the next command.
The Master's Edition will support the display of graphic illustrations
contained in the various standard .PCX graphics file formats. PCX is
(by far) the most popular of the graphics formats currently available,
and there are many, many disks filed with PCX "clip art" available from
BBSs and various Shareware disk vendors. PCX pictures can be created by
a number of popular "Paint" and/or "Draw" programs including PC
Paintbrush, Microsoft Paint, Deluxe Paint, Desktop Paint (Shareware),
Finger Paint (Shareware), and Turbo Paint (Shareware) -- to name the
most popular.
Note from Dave: I use Deluxe Paint II (from Electronic Arts). It is a
wonderful product!!
GRAPHIC CONVERSION UTILITIES
If you have a paint or draw program that does not use PCX format, you
will want to check out a number of graphics conversion programs that can
convert from a number of different picture formats to PCX format. These
conversion utilities also have other features that you will find quite
helpful, such as the ability to resize pictures, change the number of
colors, etc. Several of the best of such utilities are: HiJack (both
DOS and Windows available), Graphics Workshop (Shareware -- both DOS and
Windows available), and Paint Shop Pro (Shareware -- both DOS and
Windows available). These products are described in more detail in the
section entitled RECOMMENDED SHAREWARE UTILITIES.
SCREEN DISPLAY AND FILE EXTENSION OPTIONS
The Master's Edition can display pictures with 2, 4, 16 or 256 colors on
CGA, EGA, MCGA or VGA screen adapters. Obviously, it will not display a
256 (VGA) color picture on a screen adaptor that is limited to 4 colors
(i.e., a CGA monitor). If it is impossible to display a picture, AGT
will generate an error "beep" instead.
The specific types of pictures that AGT will display are given in the
following table:
127
"Type" "Mode" Graphics Card Resolution Colors
~~~~~~ ~~~~~~ ~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~
CGA04 $04 CGA 320 x 200 4
CGA06 $06 CGA 640 x 200 2
EGA0D $0D EGA 320 x 200 16
EGA0E $0E EGA 640 x 200 16
EGA10 $10 EGA 640 x 350 16
VGA12 $12 VGA 640 x 480 16
VGA13 $13 VGA 320 x 200 256
AGT will display either full-screen pictures (which often take a great
deal of disk space and require more time to "paint" the picture on to
the screen) or smaller pictures which will automatically be centered on
the screen. You are encouraged to make your pictures smaller than the
total screen size because the disk space required to store a large
number of PCX files can be humongous.
The normal file extension for a PCX picture is .PCX (this should not be
a major surprise).
However, AGT requires that you tell it what kind of PCX picture you wish
to display and what kind of screen display card the picture needs. The
way that you communicate this information is via the file extension you
use for your PCX file. You indicate the proper video display option by
changing the file extension as given below:
AGT File Extension "Normal" Full Screen Size and Display
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.P06 640 x 200 x 2 CGA
.P13 320 x 200 x 16 EGA
.P14 640 x 200 x 16 EGA
.P16 640 x 350 x 16 EGA
.P18 640 x 480 x 16 VGA
.P19 320 x 200 x 256 VGA
.P40 320 x 200 x 4 CGA - Palette 0
.P41 320 x 200 x 4 CGA - Palette 1
.P42 320 x 200 x 4 CGA - Palette 2
.P43 320 x 200 x 4 CGA - Palette 3
For example, if you are using your Paint program and it is set to work
in "640x350x16 EGA" mode -- but you "clip" your picture to save space
(e.g., I recommend you actually use only about 1/4 of the full screen
for the picture), you should use a .P16 file extension in order for AGT
to center and display the picture correctly.
ANIMATION DISPLAYS
Version 1.5 of the Master's Edition adds the capability to display FLI
animation files in addition to "still" PCX pictures. The FLI format is
the most widely used animation scheme and are produced by such animation
packages as Autodesk Animator, Animator Pro, 3D-Studio, PC-Animate,
128
StrataVision 3D and others. There is a great deal of FLI animation
"clip-art" available.
NOTE: FLI animation files can only be displayed on VGA (or better)
monitors. If you try to display a FLI file on a "less powerful"
monitor, you will get an error beep and nothing will be displayed.
UTILITY VIEWER
Included as part of the Master's Edition package is a utility viewer
called AGT_VIEW.EXE. Run this program to see how AGT will display your
various pictures or animations. Also included are some sample PCX
picture files in different formats and a couple of FLI animation files
for you to try out. Remember, that you must have a VGA monitor to view
the FLI animation files. You exit the AGT_VIEW program by hitting the
ESC key.
The picture and animation files are indicated in your AGT game source
files by something like the following:
PICTURES
[Intro Picture] INTRO
[First Jungle Scene] JUNGLE1
[Second Jungle Scene] JUNGLE2
[Cave Entrance Scene] CAVE-ENT
[Picture of Small Building] BUILDING
[Picture of Little Dwarf] DWARF1
[Ghost Picture] GHOST
[Goblin Picture] GOBLIN
[Picture of OFF Lantern] LAMP-OFF
[Picture of ON Lantern] LAMP-ON
. . .
[Victory Picture] VICTORY
END_PICTURES
These files would actually be the names of various PCX format picture or
FLI files on the disk -- but without the file extensions. For example,
the "Picture of the Little Dwarf" would actually be contained in the
file named DWARF1.P42 or DWARF1.P16 or DWARF1.P41, or DWARF1.FLI etc.
See the above discussion about file extensions.
There can be up to 250 picture or animation files in each AGT game. You
can "re-use" the same picture for many ROOMs, NOUNs, etc. For example,
you might illustrate an entire maze of many rooms in a cave with just a
few individual pictures.
ROOM, NOUN AND CREATURE PICTURES OR ANIMATIONS
The game designer can specify a picture or animation for a ROOM, NOUN
and/or CREATURE as follows:
129
ROOM [end of road]
End of road
NORTH [forest (near road)]
EAST [inside building]
SOUTH [valley]
WEST [hill by road]
ENTER [inside building]
FLAGS [Water] [Building] [Tree] [Road] [Stream]
#COMMENT -- There is water here!
PICTURE [Picture of Small Building]
END_ROOM
ROOM_DESCR [end of road]
You are standing at the end of a road before a small brick
building. Around you is a forest. A small stream flows out of the
building and down a gully to the south.
END_ROOM_DESCR
NOUN [ON lamp]
lantern
shining
There is a lamp shining nearby.
NOUN_SYNONYMS lamp light
WEIGHT [noun weight]
IS_LIGHT
ON
PICTURE [Picture of ON Lantern]
END_NOUN
NOUN_DESCR [ON lamp]
The lamp runs on batteries and is currently turned on. It is
shining brightly.
END_NOUN_DESCR
CREATURE [little dwarf]
dwarf
little
A little dwarf with a big knife blocks your way.
LOCATION [NoWhere]
HOSTILE
THRESHOLD 1000
TIME_THRES 1000
GENDER THING
PICTURE [Picture of Little Dwarf]
END_CREATURE
CREATURE_DESCR [little dwarf]
The dwarf is about 3 feet tall, dressed in green with red hair and
a bushy handle-bar moustache. He is quite excited and seems
determined not to let you get away. His knife is almost as big as
he is -- and it looks like it could cause grave bodily harm.
END_CREATURE_DESCR
130
The default condition/value for a ROOM, NOUN and/or CREATURE PICTURE is
[Nowhere] (i.e., zero), i.e., there is no associated picture or
animation.
When you first move to a new location, if there are pictures or
animations associated with either the location or nouns and/or creatures
at the location, AGT will display a message listing the things that can
be viewed. The player may then give a command like VIEW DWARF to see
the appropriate illustration. The "menu-driven" parser option may also
be used to VIEW things by allowing the player to select from a menu of
viewable items.
MULTIPLE ROOM PICTURES AND ANIMATIONS
There will be times in your game when you wish to have the same picture
(or animation) in many rooms and you don't want to have to have multiple
NOUNs or CREATUREs. This is handled by defining ROOM_PIX as follows:
ROOM_PIX
[Ground pix] DIRT Ground
[Sky pix] BLUESKY Sky
[Tree pix] BIGTREE3 tree
[Water pix] WATERPIC water
END_ROOM_PIX
The format is the macro definition (i.e., the [] definition such as [Sky
pix]) followed by the file name for the picture (without the extension,
e.g. DIRT) followed by the name to be used as the "noun" to refer to
this picture or thing (i.e., the DIRT picture will be displayed when you
give the command to VIEW GROUND. The name will also be displayed when
you are using the menu option and will be treated by the game as a valid
noun.
You may have a total of 30 possible room PIX definitions. Attempting to
use more that 30 will generate an error message in the MCOMPILE program.
These 30 are in addition to the 250 possible PICTURE definitions you may
have in your game.
As an example of how to use these multiple location pictures, let's add
pictures for the SKY and TREE to our previous [end of road] room as
follows:
ROOM [end of road]
End of road
NORTH [forest (near road)]
EAST [inside building]
SOUTH [valley]
WEST [hill by road]
ENTER [inside building]
FLAGS [Water] [Building] [Tree] [Road] [Stream]
#COMMENT -- There is water here!
131